00001 ;*******************************************************************************
00002 ;*                                                                             *
00003 ;*                           S T A R   R A I D E R S                           *
00004 ;*                                                                             *
00005 ;*                  for the Atari 8-bit Home Computer System                   *
00006 ;*                                                                             *
00007 ;*       Reverse engineered and documented assembly language source code       *
00008 ;*                                                                             *
00009 ;*                                     by                                      *
00010 ;*                                                                             *
00011 ;*                                Lorenz Wiest                                 *
00012 ;*                                                                             *
00013 ;*                            (lo.wiest(at)web.de)                             *
00014 ;*                                                                             *
00015 ;*                                First Release                                *
00016 ;*                                 22-SEP-2015                                 *
00017 ;*                                                                             *
00018 ;*                                 Last Update                                 *
00019 ;*                                 10-DEC-2016                                 *
00020 ;*                                                                             *
00021 ;*                STAR RAIDERS was created by Douglas Neubauer                 *
00022 ;*                  STAR RAIDERS was published by Atari Inc.                   *
00023 ;*                                                                             *
00024 ;*******************************************************************************
00025
00026 ; I wrote this document out of my own curiosity. When STAR RAIDERS was released
00027 ; in 1979 it became the killer app for the Atari 8-bit Home Computer System.
00028 ; Since then I have always been wondering what made it tick and how its (at that
00029 ; time) spectacular 3D graphics worked, especially the rotating star field.
00030 ; Impressed by "The Atari BASIC Source Book" I decided to reverse engineer the
00031 ; STAR RAIDERS 8KB ROM cartridge to recreate a fully documented assembly
00032 ; language source code file. I had no access to the original source code, so the
00033 ; only way to succeed was a combination of educated guesses, trial-and-error,
00034 ; and patience. Eventually, I made it.
00035 ;
00036 ; Essential in preparing this document were three programs I wrote:
00037 ;
00038 ; (1) A 6502-cross-assembler based on the syntax of the MAC/65 assembler for the
00039 ;     Atari 8-bit Home Computer System to create the binary file that I verified
00040 ;     against the binary of the original ROM cartridge.
00041 ;
00042 ; (2) A text formatter to layout the source code file with its copious comment
00043 ;     sections. This was a big time saver, because as the documentation grew the
00044 ;     source code had to be reformatted over and over again.
00045 ;
00046 ; (3) A symbol checker to verify that the ubiquitous symbol-value pairs in the
00047 ;     documentation match the corresponding symbol values produced by the
00048 ;     assembler.
00049 ;
00050 ; This assembly language source code file is compatible with the MAC/65
00051 ; assembler for the Atari 8-bit Home Computer System. I was able to assemble it
00052 ; on an emulated Atari running MAC/65, producing the identical binary of the ROM
00053 ; cartridge. 
00054 ;
00055 ; Your feedback is welcome! Send feedback to lo.wiest(at)web.de.
00056 ;
00057 ; Enjoy! -- Lorenz
00058
00059 ;*******************************************************************************
00060 ;*                                                                             *
00061 ;*                               N O T A T I O N                               *
00062 ;*                                                                             *
00063 ;*******************************************************************************
00064
00065 ; BITS AND BYTES
00066 ;
00067 ; o   A "byte" consists of 8 bits. They are numbered B7..0. Bit B0 is the least
00068 ;     significant bit.
00069 ;
00070 ; o   A "word" consists of 16 bits. They are numbered B15..B0. Bit B0 is the
00071 ;     least significant bit. A word is stored in low-order then high-order byte
00072 ;     order.
00073 ;
00074 ; o   The high-order byte ("high byte") of a word consists of bits B15..8 of the
00075 ;     word.
00076 ;
00077 ; o   The low-order byte ("low byte") of a word consists of bits B7..0 of the
00078 ;     word.
00079 ;
00080 ; NUMBERS
00081 ;
00082 ; o   The dollar sign ($) prefixes hexadecimal numbers.
00083 ;     Example: $101 is the decimal number 257.
00084 ;
00085 ; o   The percent sign (%) prefixes binary numbers.
00086 ;     Example: %101 is the decimal number 5.
00087 ;
00088 ; o   The asterisk (*) is a wildcard character for a single hexadecimal or
00089 ;     binary digit.
00090 ;     Example: $0*00 is a placeholder for the numbers $0000, $0100, ..., $0F00.
00091 ;
00092 ; o   The lowercase R (r) is a wildcard character for a single random
00093 ;     hexadecimal or binary digit. The random digit r is chosen by a random
00094 ;     number generator.
00095 ;     Example: %00r0 is a placeholder for the numbers %0000 or %0010.
00096 ;
00097 ; OPERATORS
00098 ;
00099 ; o   The exclamation mark (!) is the binary OR operator.
00100 ;     Example: $01!$02 is $03.
00101 ;
00102 ; o   The less-than sign (<) indicates bits B7..0 of a word.
00103 ;     Example: <$1234 is $34.
00104 ;
00105 ; o   The greater-than sign (>) indicates bits B15..8 of a word.
00106 ;     Example: >$1234 is $12.
00107 ;
00108 ; o   A pair of brackets ([]) groups mathematical expressions.
00109 ;     Example: [3-1]*4 is 8.
00110 ;
00111 ; ASSEMBLY LANGUAGE
00112 ;
00113 ; o   The uppercase A (A) indicates the accumulator register of the 6502 CPU.
00114 ;
00115 ; o   The uppercase X (X) indicates the X register of the 6502 CPU.
00116 ;
00117 ; o   The uppercase Y (Y) indicates the Y register of the 6502 CPU.
00118 ;
00119 ; o   The prefix uppercase L and dot (L.) indicates a local variable, a memory
00120 ;     location used temporarily in a subroutine.
00121 ;
00122 ; PSEUDO-FUNCTIONS
00123 ;
00124 ; o   The function ABS(<num>) returns the absolute value of <num>.
00125 ;     Example: ABS(3) returns 3.
00126 ;     Example: ABS(-3) returns 3.
00127 ;
00128 ; o   The function RND(<num1>..<num2>) returns a random integer in
00129 ;     <num1>..<num2>.
00130 ;     Example: RND(3..5) returns a random number out of 3, 4, or 5.
00131 ;
00132 ; o   The function MAX(<num1>,<num2>) returns the larger number of <num1> and
00133 ;     <num2>.
00134 ;     Example: MAX(2,4) returns 4.
00135 ;
00136 ; VECTORS
00137 ;
00138 ; o   The lowercase X (x) indicates the x-axis of the 3D coordinate system.
00139 ;
00140 ; o   The lowercase Y (y) indicates the y-axis of the 3D coordinate system.
00141 ;
00142 ; o   The lowercase Z (z) indicates the z-axis of the 3D coordinate system.
00143 ;
00144 ; o   Components of a position vector (called "coordinates") have the arbitrary
00145 ;     unit <KM> ("kilometers").
00146 ;
00147 ; o   Components of a velocity vector have the arbitrary unit <KM/H>
00148 ;     ("kilometers per hour").
00149 ;
00150 ; o   A positive component of a position vector (coordinate) in hexadecimal
00151 ;     notation is written in the form +$<hexNum> <KM>. <hexNum> is an unsigned
00152 ;     integer value.
00153 ;     Example: The starbase is +$1000 (or 4096) <KM> ahead of our starship.
00154 ;
00155 ; o   A negative component of a position vector (coordinate) in hexadecimal
00156 ;     notation is written in the form -($<hexNum>) <KM>. <hexNum> is an unsigned
00157 ;     integer value. To calculate the actual bit pattern of this coordinate
00158 ;     value compute the two's-complement of <hexNum>. See also "ON POSITION
00159 ;     VECTORS".
00160 ;     Example: The starbase is -($1000) (or -4096) <KM> behind our starship.
00161 ;
00162 ; o   An absolute component of a position vector (coordinate) in hexadecimal
00163 ;     notation is written in the form $<hexNum> <KM>. <hexNum> is an unsigned
00164 ;     integer value.
00165 ;     Example: The Zylon fighter fires when it is closer than $1000 (or 4096)
00166 ;              <KM>. 
00167 ;
00168 ; DISPLAY LIST
00169 ;
00170 ; o   The following notation is used for Display List instructions:
00171 ;
00172 ;     BLK<n>           = Display <n> blank video lines (<n> in 1..8)
00173 ;     GR1              = Display one GRAPHICS 1 row of 20 text characters
00174 ;     GR2              = Display one GRAPHICS 2 row of 20 text characters
00175 ;     GR7              = Display one GRAPHICS 7 row of 160 pixels
00176 ;     DLI              = Trigger a Display List Interrupt
00177 ;     ... @ <addr>     = Point to screen memory at address <addr>
00178 ;     JMP @ <addr>     = Jump to next Display List instruction at address <addr>
00179 ;     WAITJMP @ <addr> = Wait for vertical blank phase, then jump to next
00180 ;                        Display List instruction at address <addr>
00181 ;
00182 ; MISCELLANEOUS
00183 ;
00184 ; o   Probabilities are written in the form <percentage>% (<number of values out
00185 ;     of the possible values>:<number of possible values>).
00186 ;     Example: The probability to throw the number 3 with a die is 16% (1:6).
00187 ;
00188 ; o   A "game loop iteration" (or "game loop") is a single execution of the game
00189 ;     loop, the main program of the game.
00190 ;
00191 ; o   A "TICK" is the time span it takes to update the TV screen (1/60 s on an
00192 ;     NTSC TV system, 1/50 s on a PAL TV system).
00193 ;
00194 ; o   A pair of braces ({}) encloses color names.
00195 ;     Example: {BLACK}
00196 ;
00197 ; o   A pair of parentheses enclosing a question mark ((?)) indicates code that
00198 ;     is not well understood.
00199 ;
00200 ; o   A pair of parentheses enclosing an exclamation mark ((!)) indicates a
00201 ;     potential bug.
00202
00203 ;*******************************************************************************
00204 ;*                                                                             *
00205 ;*                               O V E R V I E W                               *
00206 ;*                                                                             *
00207 ;*******************************************************************************
00208
00209 ; ON POSITION VECTORS
00210 ;
00211 ; The game uses a 3D coordinate system with the position of our starship at the
00212 ; center of the coordinate system and the following coordinate axes:
00213 ;
00214 ; o   The x-axis points to the right.
00215 ; o   The y-axis points up.
00216 ; o   The z-axis points in flight direction.
00217 ;
00218 ; By the way, this is called a "left-handed" coordinate system.
00219 ;
00220 ; The locations of all space objects (Zylon ships, meteors, photon torpedoes,
00221 ; starbase, transfer vessel, Hyperwarp Target Marker, stars, and explosion
00222 ; fragments) are described by a "position vector".
00223 ;
00224 ; A "position vector" is composed of an x, y, and z component. The values of the
00225 ; position vector components are called the x, y, and z "coordinates". They have
00226 ; the arbitrary unit <KM>.
00227 ;
00228 ; Each coordinate is a signed 17-bit integer number, which fits into 3 bytes:
00229 ;
00230 ;     Sign     Mantissa
00231 ;          B16 B15...B8 B7....B0
00232 ;            | |      | |      |
00233 ;     0000000* ******** ********
00234 ;
00235 ; o   B16 contains the sign bit. Used values are:
00236 ;       1 -> Positive sign
00237 ;       0 -> Negative sign
00238 ; o   B15..0 contain the coordinate value (or "mantissa") as a two's-complement
00239 ;     integer number.
00240 ;
00241 ; The range of a position vector component is -65536..+65535 <KM>.
00242 ;
00243 ; Examples:
00244 ;
00245 ;     00000001 11111111 11111111 = +65535 <KM>
00246 ;     00000001 00010000 00000000 =  +4096 <KM>
00247 ;     00000001 00001111 11111111 =  +4095 <KM>
00248 ;     00000001 00000001 00000000 =   +256 <KM>
00249 ;     00000001 00000000 11111111 =   +255 <KM>
00250 ;     00000001 00000000 00010000 =    +16 <KM>
00251 ;     00000001 00000000 00001111 =    +15 <KM>
00252 ;     00000001 00000000 00000001 =     +1 <KM>
00253 ;     00000001 00000000 00000000 =     +0 <KM>
00254 ;
00255 ;     00000000 11111111 11111111 =     -1 <KM>
00256 ;     00000000 11111111 11111110 =     -2 <KM>
00257 ;     00000000 11111111 11110001 =    -15 <KM>
00258 ;     00000000 11111111 11110000 =    -16 <KM>
00259 ;     00000000 11111111 00000001 =   -255 <KM>
00260 ;     00000000 11111111 00000000 =   -256 <KM>
00261 ;     00000000 11110000 00000001 =  -4095 <KM>
00262 ;     00000000 11110000 00000000 =  -4096 <KM>
00263 ;     00000000 00000000 00000000 = -65536 <KM>
00264 ;
00265 ; The position vector for each space object is stored in 9 tables:
00266 ;
00267 ; o   XPOSSIGN ($09DE..$0A0E), XPOSHI ($0A71..$0AA1), and XPOSLO ($0B04..$0B34)
00268 ; o   YPOSSIGN ($0A0F..$0A3F), YPOSHI ($0AA2..$0AD2), and YPOSLO ($0B35..$0B65)
00269 ; o   ZPOSSIGN ($09AD..$09DD), ZPOSHI ($0A40..$0A70), and ZPOSLO ($0AD3..$0B03)
00270 ;
00271 ; There are up to 49 space objects used in the game simultaneously, thus each
00272 ; table is 49 bytes long.
00273 ;
00274 ; o   Position vectors 0..4 belong to space objects represented by PLAYERs
00275 ;     (Zylon ships, meteors, photon torpedoes, starbase, transfer vessel, and
00276 ;     Hyperwarp Target Marker).
00277 ; o   Position vectors 5..48 belong to space objects represented by PLAYFIELD
00278 ;     pixels. Position vectors 5..16 (stars, explosion fragments) are used for
00279 ;     stars, position vectors 17..48 are used for explosion fragments and star
00280 ;     trails.
00281 ;
00282 ; INFO: The x and y coordinates of space objects are converted and displayed by
00283 ; the THETA and PHI readouts of the Control Panel Display in "gradons". The
00284 ; z-coordinate is converted and displayed by the RANGE readout in "centrons".
00285 ; The conversion takes place in subroutine SHOWDIGITS ($B8CD) where the high
00286 ; byte of a coordinate (with values $00..$FF) is transformed with lookup table
00287 ; MAPTOBCD99 ($0EE9) into a BCD value of 00..99 in "gradons" or "centrons".
00288 ;
00289 ;
00290 ; ON VELOCITY VECTORS
00291 ;
00292 ; The velocities of all space objects are described by a "velocity vector". The
00293 ; velocity vector is relative to our starship.
00294 ;
00295 ; A "velocity vector" is composed of an x, y, and z component. The values of the
00296 ; velocity vector components are called the x, y, and z "velocities". They have
00297 ; the arbitrary unit <KM/H>.
00298 ;
00299 ; Each velocity vector component is an 8-bit integer number, which fits into 1
00300 ; byte:
00301 ;
00302 ;     B7 Sign
00303 ;     |
00304 ;     |B6...B0 Mantissa
00305 ;     ||     |
00306 ;     ********
00307 ;
00308 ; o   B7 contains the sign bit. Used values are:
00309 ;     0 -> Positive sign, movement along the positive coordinate axis
00310 ;          (x-velocity: right, y-velocity: up, z-velocity: in flight direction)
00311 ;     1 -> Negative sign, movement along the negative coordinate axis
00312 ;          (x-velocity: left, y-velocity: down, z-velocity: in reverse flight
00313 ;          direction)
00314 ; o   B6..B0 contain the velocity value (or "mantissa"). It is an unsigned
00315 ;     number.
00316 ;
00317 ; The range of a velocity vector component is -127..+127 <KM/H>.
00318 ;
00319 ; Examples:
00320 ;
00321 ;     01111111 = +127 <KM/H>
00322 ;     00010000 =  +16 <KM/H>
00323 ;     00001111 =  +15 <KM/H>
00324 ;     00000001 =   +1 <KM/H>
00325 ;     00000000 =   +0 <KM/H>
00326 ;
00327 ;     10000000 =   -0 <KM/H>
00328 ;     10000001 =   -1 <KM/H>
00329 ;     10001111 =  +15 <KM/H>
00330 ;     10010000 =  +16 <KM/H>
00331 ;     11111111 = -127 <KM/H>
00332 ;
00333 ; The velocity vector for each space object stored in 3 tables:
00334 ;
00335 ; o   XVEL ($0B97..$0BC7)
00336 ; o   YVEL ($0BC8..$0BF8)
00337 ; o   ZVEL ($0B66..$0B96)
00338 ;
00339 ; There are up to 49 space objects used in the game simultaneously, thus each
00340 ; table is 49 bytes long.
00341 ;
00342 ; o   Velocity vectors 0..4 belong to space objects represented by PLAYERs
00343 ;     (Zylon ships, meteors, photon torpedoes, starbase, transfer vessel, and
00344 ;     Hyperwarp Target Marker).
00345 ; o   Velocity vectors 5..48 belong to space objects represented by PLAYFIELD
00346 ;     pixels. Velocity vectors 5..16 are used for stars, velocity vectors 17..48
00347 ;     are used for explosion fragments and star trails.
00348 ;
00349 ; INFO: The velocity of our starship is converted and displayed by the VELOCITY
00350 ; readout of the Control Panel Display in "metrons per second" units. The
00351 ; conversion takes place in subroutine SHOWDIGITS ($B8CD) where our starship's
00352 ; velocity VELOCITYL ($70) (with values $00..$FF) is transformed with lookup
00353 ; table MAPTOBCD99 ($0EE9) into a BCD value of 00..99 in "metrons per second".  
00354
00355 ;*******************************************************************************
00356 ;*                                                                             *
00357 ;*                             M E M O R Y   M A P                             *
00358 ;*                                                                             *
00359 ;*******************************************************************************
00360 ;
00361 ; The following variables are not changed by a SYSTEM RESET:
00362 ;
00363 ; $62      MISSIONLEVEL
00364 ;
00365 ;          Mission level. Used values are:
00366 ;            $00 -> NOVICE mission
00367 ;            $01 -> PILOT mission
00368 ;            $02 -> WARRIOR mission
00369 ;            $03 -> COMMANDER mission
00370 ;
00371 ; $63      FKEYCODE
00372 ;
00373 ;          Function key code. Used values are:
00374 ;            $00 -> No function key pressed
00375 ;            $01 -> START function key pressed
00376 ;            $02 -> SELECT function key pressed
00377 ;
00378 ; $64      ISDEMOMODE
00379 ;
00380 ;          Indicates whether the game is in game or in demo mode. Used values
00381 ;          are:
00382 ;            $00 -> Game mode
00383 ;            $FF -> Demo mode
00384 ;
00385 ; $65      NEWTITLEPHR
00386 ;
00387 ;          New title phrase offset for the text in the title line. The new title
00388 ;          phrase is not immediately displayed in the title line but only after
00389 ;          the display time of the currently displayed title phrase has expired.
00390 ;          Thus, setting a value to NEWTITLEPHR ($65) "enqueues" the display of
00391 ;          new title phrase. Used values are:
00392 ;            $00..$7B -> Title phrase offset into PHRASETAB ($BBAA)
00393 ;            $FF      -> Hide title line
00394 ;
00395 ;          See also TITLEPHR ($D1).
00396 ;
00397 ; $66      IDLECNTHI
00398 ;
00399 ;          Idle counter (high byte). Forms a 16-bit counter together with
00400 ;          IDLECNTLO ($77), which is incremented during the execution of the
00401 ;          Vertical Blank Interrupt handler VBIHNDLR ($A6D1). IDLECNTHI ($66) is
00402 ;          reset to 0 when the joystick trigger or a keyboard key has been
00403 ;          pressed, or to 1..3 when a function key has been pressed. When
00404 ;          IDLECNTHI ($66) reaches a value of 128 (after about 10 min idle time)
00405 ;          the game enters demo mode.
00406 ;
00407 ; The following variables are set to 0 after a SYSTEM RESET:
00408 ;
00409 ; $67      ISVBISYNC
00410 ;
00411 ;          Indicates whether the Vertical Blank Interrupt handler VBIHNDLR
00412 ;          ($A6D1) is executed. Used to synchronize the execution of a new game
00413 ;          loop iteration in GAMELOOP ($A1F3) with the vertical blank phase.
00414 ;          Used values are:
00415 ;            $00 -> Halt execution at start of game loop and wait for VBI
00416 ;            $FF -> Continue execution of game loop
00417 ;
00418 ; $68..$69 MEMPTR
00419 ;
00420 ;          A 16-bit memory pointer.
00421 ;
00422 ;          Also used as a local variable.
00423 ;
00424 ; $6A..$6B DIVIDEND
00425 ;
00426 ;          A 16-bit dividend value passed in GAMELOOP ($A1F3) to subroutine
00427 ;          PROJECTION ($AA21) to calculate a division.
00428 ;
00429 ;          Also used as a local variable.
00430 ;
00431 ; $6C      Used as a local variable.
00432 ;
00433 ; $6D      JOYSTICKDELTA
00434 ;
00435 ;          Used to pass joystick directions from GAMELOOP ($A1F3) to subroutine
00436 ;          ROTATE ($B69B). Used values are:
00437 ;            $01 -> Joystick pressed right or up
00438 ;            $00 -> Joystick centered
00439 ;            $FF -> Joystick pressed left or down
00440 ;
00441 ;          Also used as a local variable.
00442 ;
00443 ; $6E      Used as a local variable.
00444 ;
00445 ; $70      VELOCITYLO
00446 ;
00447 ;          Our starship's current velocity (low byte) in <KM/H>. Forms a 16-bit
00448 ;          value together with VELOCITYHI ($C1). In subroutine UPDPANEL ($B804),
00449 ;          VELOCITYLO ($70) is mapped to a BCD-value in 00..99 and displayed by
00450 ;          the VELOCITY readout of the Control Panel Display. See also
00451 ;          NEWVELOCITY ($71).
00452 ;
00453 ; $71      NEWVELOCITY
00454 ;
00455 ;          Our starship's new velocity (low byte) in <KM/H>. It is set by
00456 ;          pressing one of the speed keys '0'..'9'. A pressed speed key is
00457 ;          mapped to the new velocity value with VELOCITYTAB ($BAB4).
00458 ;
00459 ; $72      COUNT8
00460 ;
00461 ;          Wrap-around counter. Counts from 0..7, then starts over at 0. It is
00462 ;          incremented every game loop iteration. It is used to change the
00463 ;          brightness of stars and explosion fragments more randomly in GAMELOOP
00464 ;          ($A1F3) and to slow down the movement of the hyperwarp markers of the
00465 ;          Galactic Chart in subroutine SELECTWARP ($B162).
00466 ;
00467 ; $73      EXPLLIFE
00468 ;
00469 ;          Explosion lifetime. It is decremented every game loop iteration. Used
00470 ;          values are:
00471 ;              $00 -> Explosion is over
00472 ;            < $18 -> Number of explosion fragment space objects is decremented
00473 ;            < $70 -> HITBADNESS ($8A) is reset
00474 ;              $80 -> Initial value at start of explosion
00475 ;
00476 ; $74      CLOCKTIM
00477 ;
00478 ;          Star date clock delay timer. Counts down from 40 to 0. It is
00479 ;          decremented every game loop iteration. When the timer falls below 0
00480 ;          the last digit of the star date of the Galactic Chart Panel Display
00481 ;          is increased and the timer is reset to a value of 40. 
00482 ;
00483 ; $75      DOCKSTATE
00484 ;
00485 ;          State of docking operation. Used values are:
00486 ;            $00 -> NOT DOCKED
00487 ;            $01 -> TRANSFER COMPLETE
00488 ;            $81 -> RETURN TRANSFER VESSEL
00489 ;            $FF -> ORBIT ESTABLISHED
00490 ;
00491 ; $76      COUNT256
00492 ;
00493 ;          Wrap-around counter. Counts from 0..255, then starts over at 0. It is
00494 ;          incremented every game loop iteration. It is used to make the
00495 ;          starbase pulsate in brightness in GAMELOOP ($A1F3) and to decide on
00496 ;          the creation of a meteor in subroutine MANEUVER ($AA79).
00497 ;
00498 ; $77      IDLECNTLO
00499 ;
00500 ;          Idle counter (low byte). Forms a 16-bit counter together with
00501 ;          IDLECNTHI ($66), which is incremented during the execution of the
00502 ;          Vertical Blank Interrupt handler VBIHNDLR ($A6D1).
00503 ;
00504 ;          NOTE: This variable is never properly initialized except at initial
00505 ;          cartridge startup (cold start).
00506 ;
00507 ; $78      ZYLONUNITTIM
00508 ;
00509 ;          Zylon unit movement timer. This delay timer triggers movement of
00510 ;          Zylon units on the Galactic Chart. At the start of the game, the
00511 ;          timer is initialized to a value of 100. It is decremented every 40
00512 ;          game loop iterations. When the timer falls below 0 the Zylon units
00513 ;          move on the Galactic Chart and the timer value is reset to 49. If a
00514 ;          starbase is surrounded the timer is reset to 99 to buy you some extra
00515 ;          time to destroy one of the surrounding Zylon units.
00516 ;
00517 ; $79      MAXSPCOBJIND
00518 ;
00519 ;          Maximum index of used space objects in the current game loop
00520 ;          iteration. Frequently used values are:
00521 ;            $10 -> During regular cruise (5 PLAYER space objects + 12 PLAYFIELD
00522 ;                   space objects (stars), counted $00..$10)
00523 ;            $30 -> During explosion or hyperwarp (5 PLAYER space objects + 12
00524 ;                   PLAYFIELD space objects (stars) + 32 PLAYFIELD space objects
00525 ;                   (explosion fragments or stars of star trails), counted
00526 ;                   $00..$30)
00527 ;
00528 ; $7A      OLDMAXSPCOBJIND
00529 ;
00530 ;          Maximum index of used space objects in the previous game loop
00531 ;          iteration. Frequently used values are:
00532 ;            $10 -> During regular cruise (5 PLAYER space objects + 12 PLAYFIELD
00533 ;                   space objects (stars), counted $00..$10)
00534 ;            $30 -> During explosion or hyperwarp (5 PLAYER space objects + 12
00535 ;                   PLAYFIELD space objects (stars) + 32 PLAYFIELD space objects
00536 ;                   (explosion fragments or stars of star trails), counted
00537 ;                   $00..$30)
00538 ;
00539 ; $7B      ISSTARBASESECT
00540 ;
00541 ;          Indicates whether a starbase is in this sector. Used values are:
00542 ;            $00 -> Sector contains no starbase
00543 ;            $FF -> Sector contains starbase
00544 ;
00545 ; $7C      ISTRACKCOMPON
00546 ;
00547 ;          Indicates whether the Tracking Computer is on or off. Used values
00548 ;          are:
00549 ;            $00 -> Tracking Computer is off
00550 ;            $FF -> Tracking Computer is on
00551 ;
00552 ; $7D      DRAINSHIELDS
00553 ;
00554 ;          Energy drain rate of the Shields per game loop iteration in energy
00555 ;          subunits. See also subroutine UPDPANEL ($B804). Used values are:
00556 ;            $00 -> Shields are off
00557 ;            $08 -> Shields are on
00558 ;
00559 ; $7E      DRAINATTCOMP
00560 ;
00561 ;          Energy drain rate of the Attack Computer per game loop iteration in
00562 ;          energy subunits. See also subroutine UPDPANEL ($B804). Used values
00563 ;          are:
00564 ;            $00 -> Attack Computer off
00565 ;            $02 -> Attack Computer on
00566 ;
00567 ; $7F      ENERGYCNT
00568 ;
00569 ;          Running counter of consumed energy subunits (256 energy subunits = 1
00570 ;          energy unit displayed by the 4-digit ENERGY readout of the Control
00571 ;          Panel Display). Forms an invisible fractional or "decimals" part of
00572 ;          the 4-digit ENERGY readout of the Control Panel Display. See also
00573 ;          subroutine UPDPANEL ($B804).
00574 ;
00575 ; $80      DRAINENGINES
00576 ;
00577 ;          Energy drain rate of our starship's Engines per game loop iteration
00578 ;          in energy subunits (256 energy subunits = 1 energy unit displayed by
00579 ;          the 4-digit ENERGY readout of the Control Panel Display). Values are
00580 ;          picked from table DRAINRATETAB ($BAD3). See also subroutine UPDPANEL
00581 ;          ($B804).
00582 ;
00583 ; $81      SHIELDSCOLOR
00584 ;
00585 ;          Shields color. Used values are: 
00586 ;            $00 -> {BLACK} (Shields are off)
00587 ;            $A0 -> {DARK GREEN} (Shields are on)
00588 ;
00589 ; $82      PL3HIT
00590 ;
00591 ;          Collision register of PLAYER3 (usually our starship's photon torpedo
00592 ;          0) with other PLAYERs. Used values are:
00593 ;              $00 -> No collision
00594 ;            > $00 -> PLAYER3 has collided with another PLAYER space object. See
00595 ;                     subroutine COLLISION ($AF3D) for details which PLAYER has
00596 ;                     been hit by PLAYER3.
00597 ;
00598 ; $83      PL4HIT
00599 ;
00600 ;          Collision register of PLAYER4 (usually our starship's photon torpedo
00601 ;          1) with other PLAYERs. Used values are:
00602 ;              $00 -> No collision
00603 ;            > $00 -> PLAYER4 has collided with another PLAYER space object. See
00604 ;                     subroutine COLLISION ($AF3D) for details which PLAYER has
00605 ;                     been hit by PLAYER4.
00606 ;
00607 ; $84      OLDTRIG0
00608 ;
00609 ;          Joystick trigger state. Used values are:
00610 ;            $00 -> Joystick trigger was pressed
00611 ;            $01 -> Joystick trigger was not pressed
00612 ;            $AA -> Joystick trigger was "virtually" pressed (will launch
00613 ;                   another of our starship's photon torpedoes, see subroutine
00614 ;                   TRIGGER ($AE29).
00615 ;
00616 ; $86      ISTRACKING
00617 ;
00618 ;          Indicates whether one of our starship's photon torpedoes is currently
00619 ;          tracking (homing in on) the target space object. Used values are:
00620 ;              $00 -> No target space object tracked. Our starship's photon
00621 ;                     torpedoes will fly just straight ahead.
00622 ;            > $00 -> Tracking a target space object. Our starship's photon
00623 ;                     torpedoes will home in on the tracked space object.
00624 ;
00625 ; $87      BARRELNR
00626 ;
00627 ;          Barrel from which our starship's next photon torpedo will be
00628 ;          launched. Used values are:
00629 ;            $00 -> Left barrel
00630 ;            $01 -> Right barrel
00631 ;
00632 ; $88      LOCKONLIFE
00633 ;
00634 ;          Lifetime of target lock-on. A target remains in lock-on while
00635 ;          LOCKONLIFE ($88) counts down from 12 to 0. It is decremented every
00636 ;          game loop iteration.
00637 ;
00638 ; $89      PLTRACKED
00639 ;
00640 ;          Index of currently tracked PLAYER. It is copied in subroutine TRIGGER
00641 ;          ($AE29) from TRACKDIGIT ($095C). Used values are:
00642 ;            $00 -> Track Zylon ship 0
00643 ;            $01 -> Track Zylon ship 1
00644 ;            $02 -> Track starbase during docking operations
00645 ;            $03 -> Track Hyperwarp Target Marker during hyperwarp
00646 ;
00647 ; $8A      HITBADNESS
00648 ;
00649 ;          Severity of a Zylon photon torpedo hit. Used values are:
00650 ;            $00 -> NO HIT
00651 ;            $7F -> SHIELDS HIT
00652 ;            $FF -> STARSHIP DESTROYED
00653 ;
00654 ; $8B      REDALERTLIFE
00655 ;
00656 ;          Lifetime of red alert. It decreases from 255 to 0. It is decremented
00657 ;          every game loop iteration.
00658 ;
00659 ; $8C      WARPDEPRROW
00660 ;
00661 ;          Departure hyperwarp marker row number on the Galactic Chart. It is
00662 ;          given in Player/Missile pixels relative to the top Galactic Chart
00663 ;          border. It is initialized to a value of $47 (vertical center of
00664 ;          Galactic Chart). Divide this value by 16 to get the departure sector
00665 ;          row number. Used values are: $00..$7F.
00666 ;
00667 ; $8D      WARPDEPRCOLUMN
00668 ;
00669 ;          Departure hyperwarp marker column number on the Galactic Chart. It is
00670 ;          given in Player/Missile pixels relative to the left Galactic Chart
00671 ;          border and initialized to a value of $43 (horizontal center of
00672 ;          Galactic Chart). Divide this value by 8 to get the departure sector
00673 ;          column number. Used values are: $00..$7F.
00674 ;
00675 ; $8E      WARPARRVROW
00676 ;
00677 ;          Arrival hyperwarp marker row number on the Galactic Chart in
00678 ;          Player/Missile pixels relative to top Galactic Chart border. It is
00679 ;          initialized to a value of $47 (vertical center of Galactic Chart).
00680 ;          Divide this value by 16 to get the arrival sector row number. Used
00681 ;          values are: $00..$7F. 
00682 ;
00683 ; $8F      WARPARRVCOLUMN
00684 ;
00685 ;          Arrival hyperwarp marker column number on the Galactic Chart in
00686 ;          Player/Missile pixels relative to left Galactic Chart border. It is
00687 ;          initialized to a value of $43 (horizontal center of Galactic Chart).
00688 ;          Divide this value by 8 to get the arrival sector column number. Used
00689 ;          values are: $00..$7F. 
00690 ;
00691 ; $90      CURRSECTOR
00692 ;
00693 ;          Galactic Chart sector of the current location of our starship. At the
00694 ;          start of the game it is initialized to a value of $48. Used values
00695 ;          are: $00..$7F with, for example,
00696 ;            $00 -> NORTHWEST corner sector
00697 ;            $0F -> NORTHEAST corner sector
00698 ;            $70 -> SOUTHWEST corner sector
00699 ;            $7F -> SOUTHWEST corner sector
00700 ;
00701 ;          See also ARRVSECTOR ($92). 
00702 ;
00703 ; $91      WARPENERGY
00704 ;
00705 ;          Energy required to hyperwarp between the departure and arrival
00706 ;          hyperwarp marker locations on the Galactic Chart divided by 10.
00707 ;          Values are picked from table WARPENERGYTAB ($BADD). Multiply this
00708 ;          value by 10 to get the actual value in energy units displayed by the
00709 ;          Galactic Chart Panel Display.
00710 ;
00711 ; $92      ARRVSECTOR
00712 ;
00713 ;          Galactic Chart arrival sector of our starship after hyperwarp. Used
00714 ;          values are: $00..$7F with, for example,
00715 ;            $00 -> NORTHWEST corner sector
00716 ;            $0F -> NORTHEAST corner sector
00717 ;            $70 -> SOUTHWEST corner sector
00718 ;            $7F -> SOUTHWEST corner sector
00719 ;
00720 ;          See also CURRSECTOR ($90). 
00721 ;
00722 ; $93      HUNTSECTOR
00723 ;
00724 ;          Galactic Chart sector of the starbase toward which the Zylon units
00725 ;          are currently moving. Used values are: $00..$7F with, for example,
00726 ;            $00 -> NORTHWEST corner sector
00727 ;            $0F -> NORTHEAST corner sector
00728 ;            $70 -> SOUTHWEST corner sector
00729 ;            $7F -> SOUTHWEST corner sector
00730 ;
00731 ; $94      HUNTSECTCOLUMN
00732 ;
00733 ;          Galactic Chart sector column number of the starbase toward which the
00734 ;          Zylon units are currently moving. Used values are: 0..15.
00735 ;
00736 ; $95      HUNTSECTROW
00737 ;
00738 ;          Galactic Chart sector row number of the starbase toward which the
00739 ;          Zylon units are currently moving. Used values are: 0..7.
00740 ;
00741 ; $96..$9E NEWZYLONDIST
00742 ;
00743 ;          Table of distances between a Zylon unit and the hunted starbase when
00744 ;          the Zylon unit is tentatively moved in one of the 9 possible
00745 ;          directions NORTH, NORTHWEST, WEST, SOUTHWEST, SOUTH, SOUTHEAST, EAST,
00746 ;          NORTHEAST, CENTER. Used to decide into which sector the Zylon unit
00747 ;          should move.
00748 ;
00749 ; $9E      OLDZYLONDIST
00750 ;
00751 ;          Current distance between the Zylon unit and the hunted starbase.
00752 ;
00753 ; $9F      HUNTTIM
00754 ;
00755 ;          Delay timer for Zylon units to decide on which starbase to hunt. It
00756 ;          counts down from 7. It is decremented every game loop iteration. When
00757 ;          the timer falls below 0 the Zylon units re-decide toward which
00758 ;          starbase to move.
00759 ;
00760 ; $A0      BLIPCOLUMN
00761 ;
00762 ;          Top-left screen pixel column number of blip shape displayed in the
00763 ;          Attack Computer Display. Used in subroutine UPDATTCOMP ($A7BF). Used
00764 ;          values are: 120..142.
00765 ;
00766 ; $A1      BLIPROW
00767 ;
00768 ;          Top-left screen pixel row number of blip shape displayed in the
00769 ;          Attack Computer Display. Used in subroutine UPDATTCOMP ($A7BF). Used
00770 ;          values are: 71..81.
00771 ;
00772 ; $A2      BLIPCYCLECNT
00773 ;
00774 ;          Blip cycle counter. It controls drawing the blip shape in the Attack
00775 ;          Computer Display. Its value is incremented every game loop iteration.
00776 ;          Used in subroutine UPDATTCOMP ($A7BF). Used values are:
00777 ;            $00..$04 -> Draw 0..4th row of blip shape
00778 ;            $05..$09 -> Do not draw blip shape (delay)
00779 ;            $0A      -> Recalculate blip shape position, erase Attack Computer
00780 ;                        Display
00781 ;
00782 ; $A3      ISINLOCKON
00783 ;
00784 ;          Indicates whether the tracked space object is currently in full
00785 ;          lock-on (horizontally and vertically centered as well as in range) in
00786 ;          the Attack Computer Display. If so, all lock-on markers show up on
00787 ;          the Attack Computer Display and our starship's launched photon
00788 ;          torpedoes will home in on the tracked space object. Used values are:
00789 ;            $00 -> Not in lock-on
00790 ;            $A0 -> In lock-on
00791 ;
00792 ; $A4      DIRLEN
00793 ;
00794 ;          Used to pass the direction and length of a single line to be drawn in
00795 ;          the PLAYFIELD. Used in subroutines DRAWLINES ($A76F), DRAWLINE
00796 ;          ($A782), and UPDATTCOMP ($A7BF). Used values are:
00797 ;            Bit B7 = 0 -> Draw right
00798 ;            Bit B7 = 1 -> Draw down
00799 ;            Bits B6..0 -> Length of line in pixels.
00800 ;
00801 ;          See also PENROW ($A5) and PENCOLUMN ($A6).
00802 ;
00803 ; $A5      PENROW
00804 ;
00805 ;          Used to pass the start screen pixel row number of the line to be
00806 ;          drawn in the PLAYFIELD. Used in subroutines DRAWLINES ($A76F),
00807 ;          DRAWLINE ($A782), and UPDATTCOMP ($A7BF).
00808 ;
00809 ; $A6      PENCOLUMN
00810 ;
00811 ;          Used to pass the start screen pixel column number of the line to be
00812 ;          drawn in the PLAYFIELD. Used in subroutines DRAWLINES ($A76F),
00813 ;          DRAWLINE ($A782), and UPDATTCOMP ($A7BF).
00814 ;
00815 ; $A7      CTRLDZYLON
00816 ;
00817 ;          Index of Zylon ship currently controlled by the game. Used in
00818 ;          subroutine MANEUVER ($AA79). The value is toggled every other game
00819 ;          loop iteration. Used values are:
00820 ;            $00 -> Control Zylon ship 0.
00821 ;            $01 -> Control Zylon ship 1.
00822 ;
00823 ; $A8      ZYLONFLPAT0
00824 ;
00825 ;          Flight pattern of Zylon ship 0. Used in subroutine MANEUVER ($AA79).
00826 ;          Used values are:
00827 ;            $00 -> Attack flight pattern "0"
00828 ;            $01 -> Flight pattern "1"
00829 ;            $04 -> Flight pattern "4"
00830 ;
00831 ; $A9      ZYLONFLPAT1
00832 ;
00833 ;          Flight pattern of Zylon ship 1. Compare ZYLONFLPAT0 ($A8).
00834 ;
00835 ; $AA      MILESTTIM0
00836 ;
00837 ;          Delay timer of the milestone velocity indices of Zylon ship 0. Used
00838 ;          in subroutine MANEUVER ($AA79).
00839 ;
00840 ;          When Zylon ship 0 is active, this value is decremented every game
00841 ;          loop iteration. If it falls below 0 then the milestone velocity
00842 ;          indices of Zylon ship 0 are recalculated. When Zylon ship 0 is
00843 ;          controlled by the computer for the first time, the timer is set to an
00844 ;          initial value of 1, later to an initial value of 120.
00845 ;
00846 ; $AB      MILESTTIM1
00847 ;
00848 ;          Delay timer of the milestone velocity index vector of Zylon ship 1.
00849 ;          Compare MILESTTIM0 ($AA).
00850 ;
00851 ; $AC      MILESTVELINDZ0
00852 ;
00853 ;          Milestone z-velocity index of Zylon ship 0. Used in subroutine
00854 ;          MANEUVER ($AA79). The current z-velocity index of Zylon ship 0
00855 ;          ZYLONVELINDZ0 ($B2) is compared with this index and gradually
00856 ;          adjusted to it. Used values are: 0..15.
00857 ;
00858 ; $AD      MILESTVELINDZ1
00859 ;
00860 ;          Milestone z-velocity index of Zylon ship 1. Compare MILESTVELINDZ0
00861 ;          ($AC).
00862 ;
00863 ; $AE      MILESTVELINDX0
00864 ;
00865 ;          Milestone x-velocity index of Zylon ship 0. Used in subroutine
00866 ;          MANEUVER ($AA79). The current x-velocity index of Zylon ship 0
00867 ;          ZYLONVELINDX0 ($B4) is compared with this index and gradually
00868 ;          adjusted to it. Used values are: 0..15.
00869 ;
00870 ; $AF      MILESTVELINDX1
00871 ;
00872 ;          Milestone x-velocity index of Zylon ship 1. Compare MILESTVELINDX0
00873 ;          ($AE).
00874 ;
00875 ; $B0      MILESTVELINDY0
00876 ;
00877 ;          Milestone y-velocity index of Zylon ship 0. Used in subroutine
00878 ;          MANEUVER ($AA79). The current y-velocity index of Zylon ship 0
00879 ;          ZYLONVELINDY0 ($B6) is compared with this index and gradually
00880 ;          adjusted to it. Used values are: 0..15.
00881 ;
00882 ; $B1      MILESTVELINDY1
00883 ;
00884 ;          Milestone y-velocity index of Zylon ship 1. Compare MILESTVELINDY0
00885 ;          ($B0).
00886 ;
00887 ; $B2      ZYLONVELINDZ0
00888 ;
00889 ;          Current z-velocity index of Zylon ship 0. Used in subroutine MANEUVER
00890 ;          ($AA79). It indexes velocity values in ZYLONVELTAB ($BF99). Used
00891 ;          values are: 0..15.
00892 ;
00893 ; $B3      ZYLONVELINDZ1
00894 ;
00895 ;          Current z-velocity index of Zylon ship 1. Compare ZYLONVELINDZ0
00896 ;          ($B2).
00897 ;
00898 ; $B4      ZYLONVELINDX0
00899 ;
00900 ;          Current x-velocity index of Zylon ship 0. Compare ZYLONVELINDZ0
00901 ;          ($B2).
00902 ;
00903 ; $B5      ZYLONVELINDX1
00904 ;
00905 ;          Current x-velocity index of Zylon ship 1. Compare ZYLONVELINDZ0
00906 ;          ($B2).
00907 ;
00908 ; $B6      ZYLONVELINDY0
00909 ;
00910 ;          Current y-velocity index of Zylon ship 0. Compare ZYLONVELINDZ0
00911 ;          ($B2).
00912 ;
00913 ; $B7      ZYLONVELINDY1
00914 ;
00915 ;          Current y-velocity index of Zylon ship 1. Compare ZYLONVELINDZ0
00916 ;          ($B2).
00917 ;
00918 ; $B8      ISBACKATTACK0
00919 ;
00920 ;          Indicates whether Zylon ship 0 will attack our starship from the
00921 ;          back. Used in subroutine MANEUVER ($AA79). Used values are:
00922 ;            $00 -> Zylon ship 0 attacks from the front of our starship
00923 ;            $01 -> Zylon ship 0 attacks from the front and back of our starship
00924 ;
00925 ; $B9      ISBACKATTACK1
00926 ;
00927 ;          Indicates whether Zylon ship 1 will attack our starship from the
00928 ;          back. Compare ISBACKATTACK0 ($B8).
00929 ;
00930 ; $BA      ZYLONTIMX0
00931 ;
00932 ;          Delay timer of the x-velocity index of Zylon ship 0. Used in
00933 ;          subroutine MANEUVER ($AA79). It is decremented every game loop
00934 ;          iteration. When the timer value falls below 0 the current velocity
00935 ;          index ZYLONVELINDX0 ($B4) is adjusted depending on the current
00936 ;          joystick position. The new timer value is set depending on the
00937 ;          resulting new x-velocity index. Used values are: 0, 2, 4, ..., 14.
00938 ;
00939 ; $BB      ZYLONTIMX1
00940 ;
00941 ;          Delay timer of x-velocity index of Zylon ship 1. Compare ZYLONTIMX0
00942 ;          ($BA).
00943 ;
00944 ; $BC      ZYLONTIMY0
00945 ;
00946 ;          Delay timer of y-velocity index of Zylon ship 0. Compare ZYLONTIMX0
00947 ;          ($BA).
00948 ;
00949 ; $BD      ZYLONTIMY1
00950 ;
00951 ;          Delay timer of y-velocity index of Zylon ship 1. Compare ZYLONTIMX0
00952 ;          ($BA).
00953 ;
00954 ; $BE      TORPEDODELAY
00955 ;
00956 ;          After a Zylon photon torpedo has hit our starship this delay timer is
00957 ;          initialized to a value of 2. It is decremented every game loop
00958 ;          iteration and so delays the launch of the next Zylon photon torpedo
00959 ;          for 2 game loop iterations.
00960 ;
00961 ; $BF      ZYLONATTACKER
00962 ;
00963 ;          Index of the Zylon ship that launched the Zylon photon torpedo. It is
00964 ;          used in GAMELOOP ($A1F3) to override the current tracking computer
00965 ;          settings in order to track this Zylon ship first. Used values are:
00966 ;            $00 -> Zylon photon torpedo was launched by Zylon ship 0
00967 ;            $01 -> Zylon photon torpedo was launched by Zylon ship 1
00968 ;
00969 ; $C0      WARPSTATE
00970 ;
00971 ;          Hyperwarp state. Used values are:
00972 ;            $00 -> Hyperwarp not engaged
00973 ;            $7F -> Hyperwarp engaged
00974 ;            $FF -> In hyperspace
00975 ;
00976 ; $C1      VELOCITYHI
00977 ;
00978 ;          Our starship's velocity (high byte) in <KM/H>. Used values are:
00979 ;            $00 -> Not in hyperspace (regular cruise or accelerating to
00980 ;                   hyperspace velocity)
00981 ;            $01 -> Hyperspace velocity
00982 ;
00983 ;          See also VELOCITYLO ($70). 
00984 ;
00985 ; $C2      TRAILDELAY
00986 ;
00987 ;          Delay timer to create the next star trail. Its value is decremented
00988 ;          from 3 to 0 every game loop iteration during the hyperwarp STAR TRAIL
00989 ;          PHASE in subroutine INITTRAIL ($A9B4).
00990 ;
00991 ; $C3      TRAILIND
00992 ;
00993 ;          Position vector index of the star trail's first star. Used in
00994 ;          subroutine INITTRAIL ($A9B4) to initialize a star trail, which is
00995 ;          then displayed during the hyperwarp STAR TRAIL PHASE. Used values
00996 ;          are: 17..48 in wrap-around fashion.
00997 ;
00998 ; $C4      WARPTEMPCOLUMN
00999 ;
01000 ;          Temporary arrival column number of our starship on the Galactic Chart
01001 ;          at the beginning of hyperspace. It is given in Player/Missile pixels
01002 ;          relative to the left Galactic Chart border. Divide this value by 8 to
01003 ;          get the sector column number. Used values are: $00..$7F. See also
01004 ;          WARPARRVCOLUMN ($8F).
01005 ;
01006 ; $C5      WARPTEMPROW
01007 ;
01008 ;          Temporary arrival row number of our starship on the Galactic Chart at
01009 ;          the beginning of hyperspace. It is given in Player/Missile pixels
01010 ;          relative to top Galactic Chart border. Divide this value by 16 to get
01011 ;          the sector row number.  Used values are: $00..$7F. See also
01012 ;          WARPARRVROW ($8E).
01013 ;
01014 ; $C6      VEERMASK
01015 ;
01016 ;          Limits the veer-off velocity of the Hyperwarp Target Marker during
01017 ;          the hyperwarp ACCELERATION PHASE in subroutine HYPERWARP ($A89B).
01018 ;          Values are picked from table VEERMASKTAB ($BED7).
01019 ;
01020 ;          Also used as a local variable.
01021 ;
01022 ; $C7      VICINITYMASK
01023 ;
01024 ;          Mask to confine space objects' position vector components
01025 ;          (coordinates) in a sector into a certain interval around our starship
01026 ;          after its arrival from hyperspace. Values are picked from table
01027 ;          VICINITYMASKTAB ($BFB3).
01028 ;
01029 ; $C8      JOYSTICKX
01030 ;
01031 ;          Horizontal joystick direction. Values are picked from table
01032 ;          STICKINCTAB ($BAF5). Used values are:
01033 ;            $01 -> Right
01034 ;            $00 -> Centered
01035 ;            $FF -> Left
01036 ;
01037 ; $C9      JOYSTICKY
01038 ;
01039 ;          Vertical joystick direction. Values are picked from table STICKINCTAB
01040 ;          ($BAF5). Used values are:
01041 ;            $01 -> Up
01042 ;            $00 -> Centered 
01043 ;            $FF -> Down
01044 ;
01045 ; $CA      KEYCODE
01046 ;
01047 ;          Hardware keyboard code of the pressed key on the keyboard. Shift and
01048 ;          Control key bits B7..6 are always set.
01049 ;
01050 ; $CB..$CC SCORE
01051 ;
01052 ;          Internal 16-bit score of the game in low byte-high byte order
01053 ;
01054 ; $CD      SCOREDRANKIND
01055 ;
01056 ;          Scored Rank Index. It is translated with table RANKTAB ($BEE9) to a
01057 ;          title phrase offset pointing to the rank string. Used values are: 
01058 ;            $00 -> GALACTIC COOK
01059 ;            $01 -> GARBAGE SCOW CAPTAIN
01060 ;            $02 -> GARBAGE SCOW CAPTAIN
01061 ;            $03 -> ROOKIE
01062 ;            $04 -> ROOKIE
01063 ;            $05 -> NOVICE
01064 ;            $06 -> NOVICE
01065 ;            $07 -> ENSIGN
01066 ;            $08 -> ENSIGN
01067 ;            $09 -> PILOT
01068 ;            $0A -> PILOT
01069 ;            $0B -> ACE
01070 ;            $0C -> LIEUTENANT
01071 ;            $0D -> WARRIOR
01072 ;            $0E -> CAPTAIN
01073 ;            $0F -> COMMANDER
01074 ;            $10 -> COMMANDER
01075 ;            $11 -> STAR COMMANDER
01076 ;            $12 -> STAR COMMANDER
01077 ;
01078 ; $CE      SCOREDCLASSIND
01079 ;
01080 ;          Scored Class Index. It is translated into a class number with table
01081 ;          CLASSTAB ($BEFC). Used values are:
01082 ;            $00 -> Class 5
01083 ;            $01 -> Class 5
01084 ;            $02 -> Class 5
01085 ;            $03 -> Class 4
01086 ;            $04 -> Class 4
01087 ;            $05 -> Class 4
01088 ;            $06 -> Class 4
01089 ;            $07 -> Class 3
01090 ;            $08 -> Class 3
01091 ;            $09 -> Class 3
01092 ;            $0A -> Class 2
01093 ;            $0B -> Class 2
01094 ;            $0C -> Class 2
01095 ;            $0D -> Class 1
01096 ;            $0E -> Class 1
01097 ;            $0F -> Class 1
01098 ;
01099 ; $CF      TITLELIFE
01100 ;
01101 ;          Lifetime of title line. It is decremented every game loop iteration.
01102 ;          Used initial values are:
01103 ;            $3C -> When displaying regular title phrases
01104 ;            $FE -> When displaying "STARBASE SURROUNDED", "STARBASE DESTOYED",
01105 ;                   and "RED ALERT" messages
01106 ;            $FF -> Hide title line
01107 ;
01108 ; $D0      SHIPVIEW
01109 ;
01110 ;          Current view of our starship. Values are picked from table
01111 ;          VIEWMODETAB ($BE22). Used values are:
01112 ;            $00 -> Front view
01113 ;            $01 -> Aft view
01114 ;            $40 -> Long-Range Scan view
01115 ;            $80 -> Galactic Chart view
01116 ;
01117 ; $D1      TITLEPHR
01118 ;
01119 ;          Title phrase offset for text phrase in title line. Used values are:
01120 ;            $00..$7B -> Title phrase offset into PHRASETAB ($BBAA)
01121 ;            $FF      -> Hide title line
01122 ;
01123 ;          See also NEWTITLEPHR ($65). 
01124 ;
01125 ; $D2      BEEPFRQIND
01126 ;
01127 ;          Beeper sound pattern: Running index into frequency table BEEPFRQTAB
01128 ;          ($BF5C). See also BEEPFRQSTART ($D7). See also subroutines BEEP
01129 ;          ($B3A6) and SOUND ($B2AB).
01130 ;
01131 ; $D3      BEEPREPEAT
01132 ;
01133 ;          Beeper sound pattern: Number of times the beeper sound pattern is
01134 ;          repeated - 1. See also subroutines BEEP ($B3A6) and SOUND ($B2AB).
01135 ;
01136 ; $D4      BEEPTONELIFE
01137 ;
01138 ;          Beeper sound pattern: Lifetime of tone in TICKs - 1. See also
01139 ;          subroutines BEEP ($B3A6) and SOUND ($B2AB).
01140 ;
01141 ; $D5      BEEPPAUSELIFE
01142 ;
01143 ;          Beeper sound pattern: Lifetime of pause in TICKs - 1. Used values
01144 ;          are: 
01145 ;            < $FF -> Number of TICKs - 1 to play
01146 ;              $FF -> Skip playing pause
01147 ;
01148 ;          See also subroutines BEEP ($B3A6) and SOUND ($B2AB).
01149 ;
01150 ; $D6      BEEPPRIORITY
01151 ;
01152 ;          Beeper sound pattern: Pattern priority. Each beeper sound pattern has
01153 ;          a priority. When a pattern of higher priority is about to be played
01154 ;          the pattern that is currently playing is stopped. Used values are:
01155 ;              $00 -> No pattern playing at the moment
01156 ;            > $00 -> Pattern priority
01157 ;
01158 ;          See also subroutines BEEP ($B3A6) and SOUND ($B2AB).
01159 ;
01160 ; $D7      BEEPFRQSTART
01161 ;
01162 ;          Beeper sound pattern: Index to first byte of the pattern frequency in
01163 ;          table BEEPFRQTAB ($BF5C). See also BEEPFRQIND ($D2). See also
01164 ;          subroutines BEEP ($B3A6) and SOUND ($B2AB).
01165 ;
01166 ; $D8      BEEPLIFE
01167 ;
01168 ;          Beeper sound pattern: Lifetime of the current tone or pause in TICKs.
01169 ;          It is decremented every TICK. See also subroutines BEEP ($B3A6) and
01170 ;          SOUND ($B2AB). 
01171 ;
01172 ; $D9      BEEPTOGGLE
01173 ;
01174 ;          Beeper sound pattern: Indicates that either a tone or a pause is
01175 ;          currently played. Used values are:
01176 ;            $00 -> Tone
01177 ;            $01 -> Pause
01178 ;
01179 ;          See also subroutines BEEP ($B3A6) and SOUND ($B2AB).    
01180 ;
01181 ; $DA      NOISETORPTIM
01182 ;
01183 ;          Noise sound pattern: Delay timer for PHOTON TORPEDO LAUNCHED noise
01184 ;          sound pattern. It is decremented every TICK. See also subroutines
01185 ;          NOISE ($AEA8) and SOUND ($B2AB).
01186 ;
01187 ; $DB      NOISEEXPLTIM
01188 ;
01189 ;          Noise sound pattern: Delay timer for SHIELD EXPLOSION and ZYLON
01190 ;          EXPLOSION noise sound pattern. It is decremented every TICK. See also
01191 ;          subroutines NOISE ($AEA8) and SOUND ($B2AB).
01192 ;
01193 ; $DC      NOISEAUDC2
01194 ;
01195 ;          Noise sound pattern: Audio channel 1/2 control shadow register. See
01196 ;          also subroutines NOISE ($AEA8) and SOUND ($B2AB).
01197 ;
01198 ; $DD      NOISEAUDC3
01199 ;
01200 ;          Noise sound pattern: Audio channel 3 control shadow register. See
01201 ;          also subroutines NOISE ($AEA8) and SOUND ($B2AB).
01202 ;
01203 ; $DE      NOISEAUDF1
01204 ;
01205 ;          Noise sound pattern: Audio channel 1 frequency shadow register. See
01206 ;          also subroutines NOISE ($AEA8) and SOUND ($B2AB).
01207 ;
01208 ; $DF      NOISEAUDF2
01209 ;
01210 ;          Noise sound pattern: Audio channel 2 frequency shadow register. See
01211 ;          also subroutines NOISE ($AEA8) and SOUND ($B2AB).
01212 ;
01213 ; $E0      NOISEFRQINC
01214 ;
01215 ;          Noise sound pattern: Audio channel 1/2 frequency increment. See also
01216 ;          subroutines NOISE ($AEA8) and SOUND ($B2AB).
01217 ;
01218 ; $E1      NOISELIFE
01219 ;
01220 ;          Noise sound pattern: Noise sound pattern lifetime. It is decremented
01221 ;          every TICK. See also subroutines NOISE ($AEA8) and SOUND ($B2AB).
01222 ;
01223 ; $E2      NOISEZYLONTIM
01224 ;
01225 ;          Delay timer to trigger the ZYLON EXPLOSION noise sound pattern. It is
01226 ;          set in subroutine COLLISION ($AF3D) when an impact of one of our
01227 ;          starship's photon torpedoes into a target is imminent. The timer is
01228 ;          decremented every TICK during the execution of the Vertical Blank
01229 ;          Interrupt handler VBIHNDLR ($A6D1). When the timer value reaches 0
01230 ;          the ZYLON EXPLOSION noise sound pattern is played in subroutine SOUND
01231 ;          ($B2AB). 
01232 ;
01233 ; $E3      NOISEHITLIFE
01234 ;
01235 ;          Lifetime of STARSHIP EXPLOSION noise when our starship was destroyed
01236 ;          by a Zylon photon torpedo. It is set in routine GAMELOOP ($A1F3) to a
01237 ;          value of 64 TICKs. It is decremented every TICK during the execution
01238 ;          of the Vertical Blank Interrupt handler VBIHNDLR ($A6D1).
01239 ;
01240 ; $E4      PL0SHAPOFF
01241 ;
01242 ;          PLAYER0 offset into shape table PLSHAP2TAB ($B9B1)
01243 ;
01244 ; $E5      PL1SHAPOFF
01245 ;
01246 ;          PLAYER1 offset into shape table PLSHAP2TAB ($B9B1)
01247 ;
01248 ; $E6      PL2SHAPOFF
01249 ;
01250 ;          PLAYER2 offset into shape table PLSHAP1TAB ($B8E4)
01251 ;
01252 ; $E7      PL3SHAPOFF
01253 ;
01254 ;          PLAYER3 offset into shape table PLSHAP1TAB ($B8E4)
01255 ;
01256 ; $E8      PL4SHAPOFF
01257 ;
01258 ;          PLAYER4 offset into shape table PLSHAP1TAB ($B8E4)
01259 ;
01260 ; $E9      PL0LIFE
01261 ;
01262 ;          Lifetime of the space object represented by PLAYER0 (usually Zylon
01263 ;          ship 0). Any value other than $FF is decremented with every game loop
01264 ;          iteration. Used values are:
01265 ;            $00      -> Space object not alive (= not in use)
01266 ;            $01..$FE -> Values during lifetime countdown
01267 ;            $FF      -> Infinite lifetime (not counted down)
01268 ;
01269 ; $EA      PL1LIFE
01270 ;
01271 ;          Lifetime of a space object represented by PLAYER1 (usually Zylon ship
01272 ;          1). Compare PL0LIFE ($E9).
01273 ;
01274 ; $EB      PL2LIFE
01275 ;
01276 ;          Lifetime of a space object represented by PLAYER2 (usually the Zylon
01277 ;          photon torpedo). Compare PL0LIFE ($E9).
01278 ;
01279 ;          If this PLAYER represents a photon torpedo, its lifetime is
01280 ;          decremented from an initial value of $FF.
01281 ;
01282 ; $EC      PL3LIFE
01283 ;
01284 ;          Lifetime of a space object represented by PLAYER3 (usually our
01285 ;          starship's photon torpedo 0). Compare PL2LIFE ($EB).
01286 ;
01287 ;          If this PLAYER represents a photon torpedo, its lifetime is
01288 ;          decremented from an initial value of $FF.
01289 ;
01290 ; $ED      PL4LIFE
01291 ;
01292 ;          Lifetime of a space object represented by PLAYER4 (usually our
01293 ;          starship's photon torpedo 1). Compare PL2LIFE ($EB).
01294 ;
01295 ;          If this PLAYER represents a photon torpedo, its lifetime is
01296 ;          decremented from an initial value of $FF.
01297 ;
01298 ; $EE      PL0COLOR
01299 ;
01300 ;          Color of PLAYER0
01301 ;
01302 ; $EF      PL1COLOR
01303 ;
01304 ;          Color of PLAYER1
01305 ;
01306 ; $F0      PL2COLOR
01307 ;
01308 ;          Color of PLAYER2
01309 ;
01310 ; $F1      PL3COLOR
01311 ;
01312 ;          Color of PLAYER3
01313 ;
01314 ; $F2      PF0COLOR
01315 ;
01316 ;          Color of PLAYFIELD0
01317 ;
01318 ; $F3      PF1COLOR
01319 ;
01320 ;          Color of PLAYFIELD1
01321 ;
01322 ; $F4      PF2COLOR
01323 ;
01324 ;          Color of PLAYFIELD2
01325 ;
01326 ; $F5      PF3COLOR
01327 ;
01328 ;          Color of PLAYFIELD3
01329 ;
01330 ; $F6      BGRCOLOR
01331 ;
01332 ;          Color of BACKGROUND
01333 ;
01334 ; $F7      PF0COLORDLI
01335 ;
01336 ;          Color of PLAYFIELD0 after DLI
01337 ;
01338 ; $F8      PF1COLORDLI
01339 ;
01340 ;          Color of PLAYFIELD1 after DLI
01341 ;
01342 ; $F9      PF2COLORDLI
01343 ;
01344 ;          Color of PLAYFIELD2 after DLI
01345 ;
01346 ; $FA      PF3COLORDLI
01347 ;
01348 ;          Color of PLAYFIELD3 after DLI
01349 ;
01350 ; $FB      BGRCOLORDLI
01351 ;
01352 ;          Color of BACKGROUND after DLI
01353 ;
01354 ; $0280..$02E9 DSPLST
01355 ;
01356 ;              Display List
01357 ;
01358 ; $0300..$03FF PL4DATA
01359 ;
01360 ;              PLAYER4 data area
01361 ;
01362 ; $0400..$04FF PL0DATA
01363 ;
01364 ;              PLAYER0 data area
01365 ;
01366 ; $0500..$05FF PL1DATA
01367 ;
01368 ;              PLAYER1 data area
01369 ;
01370 ; $0600..$06FF PL2DATA
01371 ;
01372 ;              PLAYER2 data area
01373 ;
01374 ; $0700..$07FF PL3DATA
01375 ;
01376 ;              PLAYER3 data area
01377 ;
01378 ; $0800..$0863 PFMEMROWLO
01379 ;
01380 ;              Lookup table of start addresses (low byte) for each row of
01381 ;              PLAYFIELD memory, which is located at PFMEM ($1000). The table
01382 ;              contains 100 bytes for 100 rows (of which only 99 are shown by
01383 ;              the Display List, the PLAYFIELD is 160 x 99 pixels). The
01384 ;              addresses grow in increments of 40 (40 bytes = 160 pixels in
01385 ;              GRAPHICS7 mode = 1 PLAYFIELD row of pixels). See also PFMEMROWHI
01386 ;              ($0864).
01387 ;
01388 ; $0864..$08C7 PFMEMROWHI
01389 ;
01390 ;              Lookup table of start addresses (high byte) of each row of
01391 ;              PLAYFIELD memory. See also PFMEMROWLO ($0800).
01392 ;
01393 ; $08C9..$0948 GCMEMMAP
01394 ;
01395 ;              Galactic Chart memory map (16 columns x 8 rows = 128 bytes)
01396 ;
01397 ; $0949..$0970 PANELTXT
01398 ;
01399 ;              Memory of Control Panel Display (bottom text window) in Front
01400 ;              view, Aft view, and Long-Range Scan view (20 characters x 2 rows
01401 ;              = 40 bytes).
01402 ;
01403 ; $094A        VELOCD1
01404 ;
01405 ;              First digit (of 2) of the VELOCITY readout in Control Panel
01406 ;              Display memory.
01407 ;
01408 ; $0950        KILLCNTD1
01409 ;
01410 ;              First digit (of 2) of the KILL COUNTER readout in Control Panel
01411 ;              Display memory.
01412 ;
01413 ; $0955        ENERGYD1
01414 ;
01415 ;              First digit (of 4) of the ENERGY readout in Control Panel Display
01416 ;              memory.
01417 ;
01418 ; $095A        TRACKC1
01419 ;
01420 ;              Character of the TRACKING readout 'T' or 'C' in Control Panel
01421 ;              Display memory.
01422 ;
01423 ; $095C        TRACKDIGIT
01424 ;
01425 ;              Digit of the TRACKING readout in Control Panel Display memory. It
01426 ;              is used to store the index of the currently tracked space object.
01427 ;              Used values are:
01428 ;                $00 -> Track Zylon ship 0
01429 ;                $01 -> Track Zylon ship 1
01430 ;                $02 -> Track starbase
01431 ;                $03 -> Track Hyperwarp Target Marker
01432 ;
01433 ; $0960        THETAC1
01434 ;
01435 ;              First character of the THETA readout in Control Panel Display
01436 ;              memory.
01437 ;
01438 ; $0966        PHIC1
01439 ;
01440 ;              First character of the PHI readout in Control Panel Display
01441 ;              memory.
01442 ;
01443 ; $096C        RANGEC1
01444 ;
01445 ;              First character of the RANGE readout in Control Panel Display
01446 ;              memory.
01447 ;
01448 ; $0971..$09AC GCTXT
01449 ;
01450 ;              Memory of Galactic Chart Panel Display (bottom text window) of
01451 ;              Galactic Chart view (20 characters x 3 rows = 60 bytes).
01452 ;
01453 ; $097D        GCWARPD1
01454 ;
01455 ;              First digit (of 4) of the HYPERWARP ENERGY readout in Galactic
01456 ;              Chart Panel Display memory.
01457 ;
01458 ; $098D        GCTRGCNT
01459 ;
01460 ;              First target counter digit (of 2) in Galactic Chart Panel Display
01461 ;              memory.
01462 ;
01463 ; $0992        GCSTATPHO
01464 ;
01465 ;              Photon Torpedo status letter in Galactic Chart Panel Display
01466 ;              memory. Used values are:
01467 ;                %00****** -> OK
01468 ;                %10****** -> Destroyed
01469 ;                %11****** -> Damaged
01470 ;
01471 ; $0993        GCSTATENG
01472 ;
01473 ;              Engines status letter in Galactic Chart Panel Display memory.
01474 ;              Used values are:
01475 ;                %00****** -> OK
01476 ;                %10****** -> Destroyed
01477 ;                %11****** -> Damaged
01478 ;
01479 ; $0994        GCSTATSHL
01480 ;
01481 ;              Shields status letter in Galactic Chart Panel Display memory.
01482 ;              Used values are:
01483 ;                %00****** -> OK
01484 ;                %10****** -> Destroyed
01485 ;                %11****** -> Damaged
01486 ;
01487 ; $0995        GCSTATCOM
01488 ;
01489 ;              Attack Computer status letter in Galactic Chart Panel Display
01490 ;              memory. Used values are:
01491 ;                %00****** -> OK
01492 ;                %10****** -> Destroyed
01493 ;                %11****** -> Damaged
01494 ;
01495 ; $0996        GCSTATLRS
01496 ;
01497 ;              Long-Range Scan status letter in Galactic Chart Panel Display
01498 ;              memory. Used values are:
01499 ;                %00****** -> OK
01500 ;                %10****** -> Destroyed
01501 ;                %11****** -> Damaged
01502 ;
01503 ; $0997        GCSTATRAD
01504 ;
01505 ;              Subspace Radio status letter in Galactic Chart Panel Display
01506 ;              memory. Used values are:
01507 ;                %00****** -> OK
01508 ;                %10****** -> Destroyed
01509 ;                %11****** -> Damaged
01510 ;
01511 ; $09A3        GCSTARDAT
01512 ;
01513 ;              First (of 5) digits of the star date clock in the Galactic Chart
01514 ;              Panel Display memory.
01515 ;
01516 ; $09AD..$09DD ZPOSSIGN
01517 ;
01518 ;              Table containing the sign bit (B16) of position vector
01519 ;              z-components (z-coordinate) (49 bytes). Bytes 0..4 belong to
01520 ;              position vectors of PLAYER space objects (Zylon ships, photon
01521 ;              torpedoes, etc.). Bytes 5..48 belong to position vectors of
01522 ;              PLAYFIELD space objects (stars, explosion fragments). Used values
01523 ;              are:
01524 ;                $00 -> Negative sign (behind our starship)
01525 ;                $01 -> Positive sign (in front of our starship)
01526 ;
01527 ;              See also "ON POSITION VECTORS".
01528 ;
01529 ; $09AD        PL0ZPOSSIGN
01530 ;
01531 ;              Sign bit (B16) of position vector z-component (z-coordinate) of
01532 ;              PLAYER0. Compare ZPOSSIGN ($09AD). See also "ON POSITION
01533 ;              VECTORS".
01534 ;
01535 ; $09AE        PL1ZPOSSIGN
01536 ;
01537 ;              Sign bit (B16) of position vector z-component (z-coordinate) of
01538 ;              PLAYER1. Compare ZPOSSIGN ($09AD). See also "ON POSITION
01539 ;              VECTORS".
01540 ;
01541 ; $09AF        PL2ZPOSSIGN
01542 ;
01543 ;              Sign bit (B16) of position vector z-component (z-coordinate) of
01544 ;              PLAYER2. Compare ZPOSSIGN ($09AD). See also "ON POSITION
01545 ;              VECTORS".
01546 ;
01547 ; $09B0        PL3ZPOSSIGN
01548 ;
01549 ;              Sign bit (B16) of position vector z-component (z-coordinate) of
01550 ;              PLAYER3. Compare ZPOSSIGN ($09AD). See also "ON POSITION
01551 ;              VECTORS".
01552 ;
01553 ; $09B1        PL4ZPOSSIGN
01554 ;
01555 ;              Sign bit (B16) of position vector z-component (z-coordinate) of
01556 ;              PLAYER4. Compare ZPOSSIGN ($09AD). See also "ON POSITION
01557 ;              VECTORS".
01558 ;
01559 ; $09DE..$0A0E XPOSSIGN
01560 ;
01561 ;              Table containing the sign bit (B16) of position vector
01562 ;              x-components (x-coordinate) (49 bytes). Bytes 0..4 belong to
01563 ;              position vectors of PLAYER space objects (Zylon ships, photon
01564 ;              torpedoes, etc.). Bytes 5..48 belong to position vectors of
01565 ;              PLAYFIELD space objects (stars, explosion fragments). Used values
01566 ;              are:
01567 ;                $00 -> Negative sign (left)
01568 ;                $01 -> Positive sign (right)
01569 ;
01570 ;              See also "ON POSITION VECTORS".
01571 ;
01572 ; $09DE        PL0XPOSSIGN
01573 ;
01574 ;              Sign bit (B16) of position vector x-component (x-coordinate) of
01575 ;              PLAYER0. Compare XPOSSIGN ($09DE). See also "ON POSITION
01576 ;              VECTORS".
01577 ;
01578 ; $09DF        PL1XPOSSIGN
01579 ;
01580 ;              Sign bit (B16) of position vector x-component (x-coordinate) of
01581 ;              PLAYER1. Compare XPOSSIGN ($09DE). See also "ON POSITION
01582 ;              VECTORS".
01583 ;
01584 ; $09E0        PL2XPOSSIGN
01585 ;
01586 ;              Sign bit (B16) of position vector x-component (x-coordinate) of
01587 ;              PLAYER2. Compare XPOSSIGN ($09DE). See also "ON POSITION
01588 ;              VECTORS".
01589 ;
01590 ; $09E1        PL3XPOSSIGN
01591 ;
01592 ;              Sign bit (B16) of position vector x-component (x-coordinate) of
01593 ;              PLAYER3. Compare XPOSSIGN ($09DE). See also "ON POSITION
01594 ;              VECTORS".
01595 ;
01596 ; $09E2        PL4XPOSSIGN
01597 ;
01598 ;              Sign bit (B16) of position vector x-component (x-coordinate) of
01599 ;              PLAYER4. Compare XPOSSIGN ($09DE). See also "ON POSITION
01600 ;              VECTORS".
01601 ;
01602 ; $0A0F..$0A3F YPOSSIGN
01603 ;
01604 ;              Table containing the sign bit (B16) of position vector
01605 ;              y-components (y-coordinate) (49 bytes). Bytes 0..4 belong to
01606 ;              position vectors of PLAYER space objects (Zylon ships, photon
01607 ;              torpedoes, etc.). Bytes 5..48 belong to position vectors of
01608 ;              PLAYFIELD space objects (stars, explosion fragments). Used values
01609 ;              are:
01610 ;                $00 -> Negative sign (down)
01611 ;                $01 -> Positive sign (up)
01612 ;
01613 ;              See also "ON POSITION VECTORS".
01614 ;
01615 ; $0A0F        PL0YPOSSIGN
01616 ;
01617 ;              Sign bit (B16) of position vector y-component (y-coordinate) of
01618 ;              PLAYER0. Compare YPOSSIGN ($0A0F). See also "ON POSITION
01619 ;              VECTORS".
01620 ;
01621 ; $0A10        PL1YPOSSIGN
01622 ;
01623 ;              Sign bit (B16) of position vector y-component (y-coordinate) of
01624 ;              PLAYER1. Compare YPOSSIGN ($0A0F). See also "ON POSITION
01625 ;              VECTORS".
01626 ;
01627 ; $0A11        PL2YPOSSIGN
01628 ;
01629 ;              Sign bit (B16) of position vector y-component (y-coordinate) of
01630 ;              PLAYER2. Compare YPOSSIGN ($0A0F). See also "ON POSITION
01631 ;              VECTORS".
01632 ;
01633 ; $0A12        PL3YPOSSIGN
01634 ;
01635 ;              Sign bit (B16) of position vector y-component (y-coordinate) of
01636 ;              PLAYER3. Compare YPOSSIGN ($0A0F). See also "ON POSITION
01637 ;              VECTORS".
01638 ;
01639 ; $0A13        PL4YPOSSIGN
01640 ;
01641 ;              Sign bit (B16) of position vector y-component (y-coordinate) of
01642 ;              PLAYER4. Compare YPOSSIGN ($0A0F). See also "ON POSITION
01643 ;              VECTORS".
01644 ;
01645 ; $0A40..$0A70 ZPOSHI
01646 ;
01647 ;              Table containing the high byte (B15..8) of position vector
01648 ;              y-components (y-coordinate) (49 bytes). Bytes 0..4 belong to
01649 ;              position vectors of PLAYER space objects (Zylon ships, photon
01650 ;              torpedoes, etc.). Bytes 5..48 belong to position vectors of
01651 ;              PLAYFIELD space objects (stars, explosion fragments). See also
01652 ;              "ON POSITION VECTORS".
01653 ;
01654 ; $0A40        PL0ZPOSHI
01655 ;
01656 ;              High byte (B15..8) of position vector z-component (z-coordinate)
01657 ;              of PLAYER0. Compare ZPOSHI ($0A40). See also "ON POSITION
01658 ;              VECTORS".
01659 ;
01660 ; $0A41        PL1ZPOSHI
01661 ;
01662 ;              High byte (B15..8) of position vector z-component (z-coordinate)
01663 ;              of PLAYER1. Compare ZPOSHI ($0A40). See also "ON POSITION
01664 ;              VECTORS".
01665 ;
01666 ; $0A42        PL2ZPOSHI
01667 ;
01668 ;              High byte (B15..8) of position vector z-component (z-coordinate)
01669 ;              of PLAYER2. Compare ZPOSHI ($0A40). See also "ON POSITION
01670 ;              VECTORS".
01671 ;
01672 ; $0A43        PL3ZPOSHI
01673 ;
01674 ;              High byte (B15..8) of position vector z-component (z-coordinate)
01675 ;              of PLAYER3. Compare ZPOSHI ($0A40). See also "ON POSITION
01676 ;              VECTORS".
01677 ;
01678 ; $0A44        PL4ZPOSHI
01679 ;
01680 ;              High byte (B15..8) of position vector z-component (z-coordinate)
01681 ;              of PLAYER4. Compare ZPOSHI ($0A40). See also "ON POSITION
01682 ;              VECTORS".
01683 ;
01684 ; $0A71..$0AA1 XPOSHI
01685 ;
01686 ;              Table containing the high byte (B15..8) of position vector
01687 ;              x-components (x-coordinate) (49 bytes). Bytes 0..4 belong to
01688 ;              position vectors of PLAYER space objects (Zylon ships, photon
01689 ;              torpedoes, etc.). Bytes 5..48 belong to position vectors of
01690 ;              PLAYFIELD space objects (stars, explosion fragments). See also
01691 ;              "ON POSITION VECTORS".
01692 ;
01693 ; $0A71        PL0XPOSHI
01694 ;
01695 ;              High byte (B15..8) of position vector x-component (x-coordinate)
01696 ;              of PLAYER0. Compare XPOSHI ($0A71). See also "ON POSITION
01697 ;              VECTORS".
01698 ;
01699 ; $0A72        PL1XPOSHI
01700 ;
01701 ;              High byte (B15..8) of position vector x-component (x-coordinate)
01702 ;              of PLAYER1. Compare XPOSHI ($0A71). See also "ON POSITION
01703 ;              VECTORS".
01704 ;
01705 ; $0A73        PL2XPOSHI
01706 ;
01707 ;              High byte (B15..8) of position vector x-component (x-coordinate)
01708 ;              of PLAYER2. Compare XPOSHI ($0A71). See also "ON POSITION
01709 ;              VECTORS".
01710 ;
01711 ; $0A74        PL3XPOSHI
01712 ;
01713 ;              High byte (B15..8) of position vector x-component (x-coordinate)
01714 ;              of PLAYER3. Compare XPOSHI ($0A71). See also "ON POSITION
01715 ;              VECTORS".
01716 ;
01717 ; $0A75        PL4XPOSHI
01718 ;
01719 ;              High byte (B15..8) of position vector x-component (x-coordinate)
01720 ;              of PLAYER4. Compare XPOSHI ($0A71). See also "ON POSITION
01721 ;              VECTORS".
01722 ;
01723 ; $0AA2..$0AD2 YPOSHI
01724 ;
01725 ;              Table containing the high byte (B15..8) of position vector
01726 ;              y-components (y-coordinate) (49 bytes). Bytes 0..4 belong to
01727 ;              position vectors of PLAYER space objects (Zylon ships, photon
01728 ;              torpedoes, etc.). Bytes 5..48 belong to position vectors of
01729 ;              PLAYFIELD space objects (stars, explosion fragments). See also
01730 ;              "ON POSITION VECTORS".
01731 ;
01732 ; $0AA2        PL0YPOSHI
01733 ;
01734 ;              High byte (B15..8) of position vector y-component (y-coordinate)
01735 ;              of PLAYER0. Compare YPOSHI ($0AA2). See also "ON POSITION
01736 ;              VECTORS".
01737 ;
01738 ; $0AA3        PL1YPOSHI
01739 ;
01740 ;              High byte (B15..8) of position vector y-component (y-coordinate)
01741 ;              of PLAYER1. Compare YPOSHI ($0AA2). See also "ON POSITION
01742 ;              VECTORS".
01743 ;
01744 ; $0AA4        PL2YPOSHI
01745 ;
01746 ;              High byte (B15..8) of position vector y-component (y-coordinate)
01747 ;              of PLAYER2. Compare YPOSHI ($0AA2). See also "ON POSITION
01748 ;              VECTORS".
01749 ;
01750 ; $0AA5        PL3YPOSHI
01751 ;
01752 ;              High byte (B15..8) of position vector y-component (y-coordinate)
01753 ;              of PLAYER3. Compare YPOSHI ($0AA2). See also "ON POSITION
01754 ;              VECTORS".
01755 ;
01756 ; $0AA6        PL4YPOSHI
01757 ;
01758 ;              High byte (B15..8) of position vector y-component (y-coordinate)
01759 ;              of PLAYER4. Compare YPOSHI ($0AA2). See also "ON POSITION
01760 ;              VECTORS".
01761 ;
01762 ; $0AD3..$0B03 ZPOSLO
01763 ;
01764 ;              Table containing the low byte (B7..0) of position vector
01765 ;              z-components (z-coordinate) (49 bytes). Bytes 0..4 belong to
01766 ;              position vectors of PLAYER space objects (Zylon ships, photon
01767 ;              torpedoes, etc.). Bytes 5..48 belong to position vectors of
01768 ;              PLAYFIELD space objects (stars, explosion fragments). See also
01769 ;              "ON POSITION VECTORS".
01770 ;
01771 ; $0AD3        PL0ZPOSLO
01772 ;
01773 ;              Low byte (B7..0) of position vector z-component (z-coordinate) of
01774 ;              PLAYER0. Compare ZPOSLO ($0AD3). See also "ON POSITION VECTORS".
01775 ;
01776 ; $0AD4        PL1ZPOSLO
01777 ;
01778 ;              Low byte (B7..0) of position vector z-component (z-coordinate) of
01779 ;              PLAYER1. Compare ZPOSLO ($0AD3). See also "ON POSITION VECTORS".
01780 ;
01781 ; $0AD5        PL2ZPOSLO
01782 ;
01783 ;              Low byte (B7..0) of position vector z-component (z-coordinate) of
01784 ;              PLAYER2. Compare ZPOSLO ($0AD3). See also "ON POSITION VECTORS".
01785 ;
01786 ; $0AD6        PL3ZPOSLO
01787 ;
01788 ;              Low byte (B7..0) of position vector z-component (z-coordinate) of
01789 ;              PLAYER3. Compare ZPOSLO ($0AD3). See also "ON POSITION VECTORS".
01790 ;
01791 ; $0AD7        PL4ZPOSLO
01792 ;
01793 ;              Low byte (B7..0) of position vector z-component (z-coordinate) of
01794 ;              PLAYER4. Compare ZPOSLO ($0AD3). See also "ON POSITION VECTORS".
01795 ;
01796 ; $0B04..$0B34 XPOSLO
01797 ;
01798 ;              Table containing the low byte (B7..0) of position vector
01799 ;              x-components (x-coordinate) (49 bytes). Bytes 0..4 belong to
01800 ;              position vectors of PLAYER space objects (Zylon ships, photon
01801 ;              torpedoes, etc.). Bytes 5..48 belong to position vectors of
01802 ;              PLAYFIELD space objects (stars, explosion fragments). See also
01803 ;              "ON POSITION VECTORS".
01804 ;
01805 ; $0B04        PL0XPOSLO
01806 ;
01807 ;              Low byte (B7..0) of position vector x-component (x-coordinate) of
01808 ;              PLAYER0. Compare XPOSLO ($0B04). See also "ON POSITION VECTORS".
01809 ;
01810 ; $0B05        PL1XPOSLO
01811 ;
01812 ;              Low byte (B7..0) of position vector x-component (x-coordinate) of
01813 ;              PLAYER1. Compare XPOSLO ($0B04). See also "ON POSITION VECTORS".
01814 ;
01815 ; $0B06        PL2XPOSLO
01816 ;
01817 ;              Low byte (B7..0) of position vector x-component (x-coordinate) of
01818 ;              PLAYER2. Compare XPOSLO ($0B04). See also "ON POSITION VECTORS".
01819 ;
01820 ; $0B07        PL3XPOSLO
01821 ;
01822 ;              Low byte (B7..0) of position vector x-component (x-coordinate) of
01823 ;              PLAYER3. Compare XPOSLO ($0B04). See also "ON POSITION VECTORS".
01824 ;
01825 ; $0B08        PL4XPOSLO
01826 ;
01827 ;              Low byte (B7..0) of position vector x-component (x-coordinate) of
01828 ;              PLAYER4. Compare XPOSLO ($0B04). See also "ON POSITION VECTORS".
01829 ;
01830 ; $0B35..$0B65 YPOSLO
01831 ;
01832 ;              Table containing the low byte (B7..0) of position vector
01833 ;              y-components (y-coordinate) (49 bytes). Bytes 0..4 belong to
01834 ;              position vectors of PLAYER space objects (Zylon ships, photon
01835 ;              torpedoes, etc.). Bytes 5..48 belong to position vectors of
01836 ;              PLAYFIELD space objects (stars, explosion fragments). See also
01837 ;              "ON POSITION VECTORS".
01838 ;
01839 ; $0B35        PL0YPOSLO
01840 ;
01841 ;              Low byte (B7..0) of position vector y-component (y-coordinate) of
01842 ;              PLAYER0. Compare YPOSLO ($0B35). See also "ON POSITION VECTORS". 
01843 ;
01844 ; $0B36        PL1YPOSLO
01845 ;
01846 ;              Low byte (B7..0) of position vector y-component (y-coordinate) of
01847 ;              PLAYER1. Compare YPOSLO ($0B35). See also "ON POSITION VECTORS".
01848 ;
01849 ; $0B37        PL2YPOSLO
01850 ;
01851 ;              Low byte (B7..0) of position vector y-component (y-coordinate) of
01852 ;              PLAYER2. Compare YPOSLO ($0B35). See also "ON POSITION VECTORS".
01853 ;
01854 ; $0B38        PL3YPOSLO
01855 ;
01856 ;              Low byte (B7..0) of position vector y-component (y-coordinate) of
01857 ;              PLAYER3. Compare YPOSLO ($0B35). See also "ON POSITION VECTORS".
01858 ;
01859 ; $0B39        PL4YPOSLO
01860 ;
01861 ;              Low byte (B7..0) of position vector y-component (y-coordinate) of
01862 ;              PLAYER4. Compare YPOSLO ($0B35). See also "ON POSITION VECTORS".
01863 ;
01864 ; $0B66..$0B96 ZVEL
01865 ;
01866 ;              Table containing velocity vector z-components (z-velocities) (49
01867 ;              bytes). Bytes 0..4 belong to velocity vectors of PLAYER space
01868 ;              objects (Zylon ships, photon torpedoes, etc.). Bytes 5..48 belong
01869 ;              to velocity vectors of PLAYFIELD space objects (stars, explosion
01870 ;              fragments). Each z-velocity is stored in the binary format
01871 ;              %sxxxxxxx where
01872 ;                %s = 0   -> Positive sign (moving in flight direction)
01873 ;                %s = 1   -> Negative sign (moving in reverse flight direction)
01874 ;                %xxxxxxx -> Unsigned 7-bit velocity value in <KM/H>
01875 ;
01876 ;              See also "ON VELOCITY VECTORS".
01877 ;
01878 ; $0B66        PL0ZVEL
01879 ;
01880 ;              Velocity vector z-component (z-velocity) of PLAYER0. Compare ZVEL
01881 ;              ($0B66). See also "ON VELOCITY VECTORS".
01882 ;
01883 ; $0B67        PL1ZVEL
01884 ;
01885 ;              Velocity vector z-component (z-velocity) of PLAYER1. Compare ZVEL
01886 ;              ($0B66). See also "ON VELOCITY VECTORS".
01887 ;
01888 ; $0B68        PL2ZVEL
01889 ;
01890 ;              Velocity vector z-component (z-velocity) of PLAYER2. Compare ZVEL
01891 ;              ($0B66). See also "ON VELOCITY VECTORS".
01892 ;
01893 ; $0B69        PL3ZVEL
01894 ;
01895 ;              Velocity vector z-component (z-velocity) of PLAYER3. Compare ZVEL
01896 ;              ($0B66). See also "ON VELOCITY VECTORS".
01897 ;
01898 ; $0B6A        PL4ZVEL
01899 ;
01900 ;              Velocity vector z-component (z-velocity) of PLAYER4. Compare ZVEL
01901 ;              ($0B66). See also "ON VELOCITY VECTORS".
01902 ;
01903 ; $0B97..$0BC7 XVEL
01904 ;
01905 ;              Table containing velocity vector x-components (x-velocities) (49
01906 ;              bytes). Bytes 0..4 belong to velocity vectors of PLAYER space
01907 ;              objects (Zylon ships, photon torpedoes, etc.). Bytes 5..48 belong
01908 ;              to velocity vectors of PLAYFIELD space objects (stars, explosion
01909 ;              fragments). Each x-velocity is stored in the binary format
01910 ;              %sxxxxxxx where
01911 ;                %s = 0   -> Positive sign (moving to the right)
01912 ;                %s = 1   -> Negative sign (moving to the left)
01913 ;                %xxxxxxx -> Unsigned 7-bit velocity value in <KM/H>
01914 ;
01915 ;              See also "ON VELOCITY VECTORS".
01916 ;
01917 ; $0B97        PL0XVEL
01918 ;
01919 ;              Velocity vector x-component (x-velocity) of PLAYER0. Compare XVEL
01920 ;              ($0B97). See also "ON VELOCITY VECTORS". 
01921 ;
01922 ; $0B98        PL1XVEL
01923 ;
01924 ;              Velocity vector x-component (x-velocity) of PLAYER1. Compare XVEL
01925 ;              ($0B97). See also "ON VELOCITY VECTORS".
01926 ;
01927 ; $0B99        PL2XVEL
01928 ;
01929 ;              Velocity vector x-component (x-velocity) of PLAYER2. Compare XVEL
01930 ;              ($0B97). See also "ON VELOCITY VECTORS".
01931 ;
01932 ; $0B9A        PL3XVEL
01933 ;
01934 ;              Velocity vector x-component (x-velocity) of PLAYER3. Compare XVEL
01935 ;              ($0B97). See also "ON VELOCITY VECTORS".
01936 ;
01937 ; $0B9B        PL4XVEL
01938 ;
01939 ;              Velocity vector x-component (x-velocity) of PLAYER4. Compare XVEL
01940 ;              ($0B97). See also "ON VELOCITY VECTORS".
01941 ;
01942 ; $0BC8..$0BF8 YVEL
01943 ;
01944 ;              Table containing velocity vector y-components (y-velocities) (49
01945 ;              bytes). Bytes 0..4 belong to velocity vectors of PLAYER space
01946 ;              objects (Zylon ships, photon torpedoes, etc.). Bytes 5..48 belong
01947 ;              to velocity vectors of PLAYFIELD space objects (stars, explosion
01948 ;              fragments). Each y-velocity is stored in the binary format
01949 ;              %sxxxxxxx where
01950 ;                %s = 0   -> Positive sign (moving up)
01951 ;                %s = 1   -> Negative sign (moving down)
01952 ;                %xxxxxxx -> Unsigned 7-bit velocity value in <KM/H>
01953 ;
01954 ;              See also "ON VELOCITY VECTORS".
01955 ;
01956 ; $0BC8        PL0YVEL
01957 ;
01958 ;              Velocity vector y-component (y-velocity) of PLAYER0. Compare YVEL
01959 ;              ($0BC8). See also "ON VELOCITY VECTORS". 
01960 ;
01961 ; $0BC9        PL1YVEL
01962 ;
01963 ;              Velocity vector y-component (y-velocity) of PLAYER1. Compare YVEL
01964 ;              ($0BC8). See also "ON VELOCITY VECTORS".
01965 ;
01966 ; $0BCA        PL2YVEL
01967 ;
01968 ;              Velocity vector y-component (y-velocity) of PLAYER2. Compare YVEL
01969 ;              ($0BC8). See also "ON VELOCITY VECTORS".
01970 ;
01971 ; $0BCB        PL3YVEL
01972 ;
01973 ;              Velocity vector y-component (y-velocity) of PLAYER3. Compare YVEL
01974 ;              ($0BC8). See also "ON VELOCITY VECTORS".
01975 ;
01976 ; $0BCC        PL4YVEL
01977 ;
01978 ;              Velocity vector y-component (y-velocity) of PLAYER4. Compare YVEL
01979 ;              ($0BC8). See also "ON VELOCITY VECTORS".
01980 ;
01981 ; $0BF9..$0C29 PIXELROWNEW
01982 ;
01983 ;              Table containing the new pixel row number of space objects (49
01984 ;              bytes). Bytes 0..4 belong to PLAYER space objects and contain
01985 ;              Player/Missile (PM) pixel row numbers. They are counted from
01986 ;              vertical PM position 0, which is offscreen. Bytes 5..48 belong to
01987 ;              PLAYFIELD space objects (stars, explosion fragments) and contain
01988 ;              PLAYFIELD pixel row numbers. They are counted from the top border
01989 ;              of the PLAYFIELD and have values of 0..99. See also PIXELROW
01990 ;              ($0C5B).
01991 ;
01992 ; $0BF9        PL0ROWNEW
01993 ;
01994 ;              New pixel row number of PLAYER0 in Player/Missile pixels. See
01995 ;              also PIXELROWNEW ($0BF9).
01996 ;
01997 ; $0BFA        PL1ROWNEW
01998 ;
01999 ;              New pixel row number of PLAYER1 in Player/Missile pixels. See
02000 ;              also PIXELROWNEW ($0BF9).
02001 ;
02002 ; $0BFB        PL2ROWNEW
02003 ;
02004 ;              New pixel row number of PLAYER2 in Player/Missile pixels. See
02005 ;              also PIXELROWNEW ($0BF9).
02006 ;
02007 ; $0BFC        PL3ROWNEW
02008 ;
02009 ;              New pixel row number of PLAYER3 in Player/Missile pixels. See
02010 ;              also PIXELROWNEW ($0BF9).
02011 ;
02012 ; $0BFD        PL4ROWNEW
02013 ;
02014 ;              New pixel row number of PLAYER4 in Player/Missile pixels. See
02015 ;              also PIXELROWNEW ($0BF9).
02016 ;
02017 ; $0C2A..$0C5A PIXELCOLUMN
02018 ;
02019 ;              Table containing the pixel column number of space objects (49
02020 ;              bytes). Bytes 0..4 belong to PLAYER space objects and contain
02021 ;              Player/Missile (PM) pixel column numbers. They are counted from
02022 ;              horizontal PM position 0, which is offscreen. Bytes 5..48 belong
02023 ;              to PLAYFIELD space objects (stars, explosion fragments) and
02024 ;              contain PLAYFIELD pixel column numbers. They are counted from the
02025 ;              left border of the PLAYFIELD and have values of 0..159.
02026 ;
02027 ; $0C2A        PL0COLUMN
02028 ;
02029 ;              Pixel column number of PLAYER0 in Player/Missile pixels. See also
02030 ;              PIXELCOLUMN ($0C2A).
02031 ;
02032 ; $0C2B        PL1COLUMN
02033 ;
02034 ;              Pixel column number of PLAYER1 in Player/Missile pixels. See also
02035 ;              PIXELCOLUMN ($0C2A).
02036 ;
02037 ; $0C2C        PL2COLUMN
02038 ;
02039 ;              Pixel column number of PLAYER2 in Player/Missile pixels. See also
02040 ;              PIXELCOLUMN ($0C2A).
02041 ;
02042 ; $0C2D        PL3COLUMN
02043 ;
02044 ;              Pixel column number of PLAYER3 in Player/Missile pixels. See also
02045 ;              PIXELCOLUMN ($0C2A).
02046 ;
02047 ; $0C2E        PL4COLUMN
02048 ;
02049 ;              Pixel column number of PLAYER4 in Player/Missile pixels. See also
02050 ;              PIXELCOLUMN ($0C2A).
02051 ;
02052 ; $0C5B..$0C8B PIXELROW
02053 ;
02054 ;              Table containing the pixel row number of space objects (49
02055 ;              bytes). Bytes 0..4 belong to PLAYER space objects and contain
02056 ;              Player/Missile (PM) pixel row numbers. They are counted from
02057 ;              vertical PM position 0, which is offscreen. Bytes 5..48 belong to
02058 ;              PLAYFIELD space objects (stars, explosion fragments) and contain
02059 ;              PLAYFIELD pixel row numbers. They are counted from the top border
02060 ;              of the PLAYFIELD and have values of 0..99. See also PIXELROWNEW
02061 ;              ($0BF9).
02062 ;
02063 ; $0C5B        PL0ROW
02064 ;
02065 ;              Pixel row number of PLAYER0 in Player/Missile pixels. See also
02066 ;              PIXELROW ($0C5B).
02067 ;
02068 ; $0C5C        PL1ROW
02069 ;
02070 ;              Pixel row number of PLAYER1 in Player/Missile pixels. See also
02071 ;              PIXELROW ($0C5B).
02072 ;
02073 ; $0C5D        PL2ROW
02074 ;
02075 ;              Pixel row number of PLAYER2 in Player/Missile pixels. See also
02076 ;              PIXELROW ($0C5B).
02077 ;
02078 ; $0C5E        PL3ROW
02079 ;
02080 ;              Pixel row number of PLAYER3 in Player/Missile pixels. See also
02081 ;              PIXELROW ($0C5B).
02082 ;
02083 ; $0C5F        PL4ROW
02084 ;
02085 ;              Pixel row number of PLAYER4 in Player/Missile pixels. See also
02086 ;              PIXELROW ($0C5B).
02087 ;
02088 ; $0C8C..$0CBC PIXELBYTEOFF
02089 ;
02090 ;              Table containing a byte offset into PLAYFIELD memory for each
02091 ;              PLAYFIELD space object (stars, explosion fragments) (49 bytes):
02092 ;              the number of bytes from the start of the PLAYFIELD row to the
02093 ;              byte containing the space object pixel in the same PLAYFIELD row.
02094 ;              In other words, the pixel column modulo 4 (1 byte = 4 GRAPHICS7
02095 ;              pixels).
02096 ;
02097 ;              NOTE: Only bytes 5..48 are used for PLAYFIELD space objects in
02098 ;              this way. Bytes 0..4 are used differently. See PL0SHAPTYPE
02099 ;              ($0C8C)..PL4SHAPTYPE ($0C90).
02100 ;
02101 ; $0C8C        PL0SHAPTYPE
02102 ;
02103 ;              Shape type of PLAYER0. Used to index the PLAYER's set of shape
02104 ;              cells in tables PLSHAPOFFTAB ($BE2F) and PLSHAPHEIGHTTAB ($BE7F).
02105 ;              Used values are:
02106 ;                $00 -> PHOTON TORPEDO
02107 ;                $10 -> ZYLON FIGHTER
02108 ;                $20 -> STARBASE RIGHT
02109 ;                $30 -> STARBASE CENTER
02110 ;                $40 -> STARBASE LEFT
02111 ;                $50 -> TRANSFER VESSEL
02112 ;                $60 -> METEOR
02113 ;                $70 -> ZYLON CRUISER
02114 ;                $80 -> ZYLON BASESTAR
02115 ;                $90 -> HYPERWARP TARGET MARKER
02116 ;
02117 ; $0C8D        PL1SHAPTYPE
02118 ;
02119 ;              Shape type of PLAYER1. Compare PL0SHAPTYPE ($0C8C).
02120 ;
02121 ; $0C8E        PL2SHAPTYPE
02122 ;
02123 ;              Shape type of PLAYER2. Compare PL0SHAPTYPE ($0C8C).
02124 ;
02125 ; $0C8F        PL3SHAPTYPE
02126 ;
02127 ;              Shape type of PLAYER3. Compare PL0SHAPTYPE ($0C8C).
02128 ;
02129 ; $0C90        PL4SHAPTYPE
02130 ;
02131 ;              Shape type of PLAYER4. Compare PL0SHAPTYPE ($0C8C).
02132 ;
02133 ; $0CBD..$0CED PIXELSAVE
02134 ;
02135 ;              Table containing the byte of PLAYFIELD memory before drawing the
02136 ;              PLAYFIELD space object pixel into it (star, explosion fragments),
02137 ;              for each PLAYFIELD space object (49 bytes). 
02138 ;
02139 ;              NOTE: Only bytes 5..48 are used for PLAYFIELD space objects in
02140 ;              this way. Bytes 0..4 are used differently. See PL0HEIGHT
02141 ;              ($0CBD)..PL4HEIGHT ($0CC1).
02142 ;
02143 ; $0CBD        PL0HEIGHT
02144 ;
02145 ;              Shape height of PLAYER0
02146 ;
02147 ; $0CBE        PL1HEIGHT
02148 ;
02149 ;              Shape height of PLAYER1
02150 ;
02151 ; $0CBF        PL2HEIGHT
02152 ;
02153 ;              Shape height of PLAYER2
02154 ;
02155 ; $0CC0        PL3HEIGHT
02156 ;
02157 ;              Shape height of PLAYER3
02158 ;
02159 ; $0CC1        PL4HEIGHT
02160 ;
02161 ;              Shape height of PLAYER4
02162 ;
02163 ; $0CEE..$0D1E PIXELBYTE
02164 ;
02165 ;              Table containing a 1-byte bit pattern for 4 pixels in the color
02166 ;              of the space object's pixel, for each PLAYFIELD space object (49
02167 ;              bytes). 
02168 ;
02169 ;              NOTE: Only bytes 5..48 are used for PLAYFIELD space objects in
02170 ;              this way. Bytes 0..4 are used differently. See PL0HEIGHTNEW
02171 ;              ($0CEE)..PL4HEIGHTNEW ($0CF2).
02172 ;
02173 ; $0CEE        PL0HEIGHTNEW
02174 ;
02175 ;              New shape height of PLAYER0
02176 ;
02177 ; $0CEF        PL1HEIGHTNEW
02178 ;
02179 ;              New shape height of PLAYER1
02180 ;
02181 ; $0CF0        PL2HEIGHTNEW
02182 ;
02183 ;              New shape height of PLAYER2
02184 ;
02185 ; $0CF1        PL3HEIGHTNEW
02186 ;
02187 ;              New shape height of PLAYER3
02188 ;
02189 ; $0CF2        PL4HEIGHTNEW
02190 ;
02191 ;              New shape height of PLAYER4
02192 ;
02193 ; $0D1F..$0D32 TITLETXT
02194 ;
02195 ;              Title text line, contains ATASCII-coded characters (20 bytes)
02196 ;
02197 ; $0D35..$0DE8 GCPFMEM
02198 ;
02199 ;              Galactic Chart PLAYFIELD memory (20 characters x 9 rows = 180
02200 ;              bytes)
02201 ;
02202 ; $0DE9..$0EE8 MAPTO80
02203 ;
02204 ;              Lookup table to convert values in $00..$FF to values of 0..80
02205 ;              (255 bytes). Used to map position vector components (coordinates)
02206 ;              to pixel row or column numbers relative to the PLAYFIELD center. 
02207 ;
02208 ; $0EE9..$0FE8 MAPTOBCD99
02209 ;
02210 ;              Lookup table to convert values in $00..$FF to BCD-values of
02211 ;              00..99 (255 bytes). Used in subroutines UPDPANEL ($B804) and
02212 ;              SHOWDIGITS ($B8CD) to convert values to a 2-digit decimal readout
02213 ;              value of the Control Panel Display.
02214 ;
02215 ; $1000..$1F77 PFMEM
02216 ;
02217 ;              PLAYFIELD graphics memory (40 bytes x 100 rows = 4000 bytes, 1
02218 ;              byte stores 4 pixels, 40 bytes = 160 pixels in GRAPHICS7 mode = 1
02219 ;              PLAYFIELD row of pixels).
02220 ;
02221 ;              NOTE: The Display List displays only PLAYFIELD rows 0..98.
02222
02223 ;*******************************************************************************
02224 ;*                                                                             *
02225 ;*                         S Y S T E M   S Y M B O L S                         *
02226 ;*                                                                             *
02227 ;*******************************************************************************
02228
02229 VDSLST          = $0200                           ; Display List Interrupt (DLI) vector
02230 VIMIRQ          = $0216                           ; Interrupt request (IRQ) immediate vector
02231 VVBLKI          = $0222                           ; Vertical blank immediate vector
02232 HPOSP0          = $D000                           ; Horizontal position of PLAYER0
02233 HPOSP1          = $D001                           ; Horizontal position of PLAYER1
02234 HPOSP2          = $D002                           ; Horizontal position of PLAYER2
02235 HPOSP3          = $D003                           ; Horizontal position of PLAYER3
02236 HPOSM0          = $D004                           ; Horizontal position of MISSILE0
02237 HPOSM1          = $D005                           ; Horizontal position of MISSILE1
02238 HPOSM2          = $D006                           ; Horizontal position of MISSILE2
02239 HPOSM3          = $D007                           ; Horizontal position of MISSILE3
02240 M0PL            = $D008                           ; MISSILE0 to PLAYER collisions
02241 M1PL            = $D009                           ; MISSILE1 to PLAYER collisions
02242 M2PL            = $D00A                           ; MISSILE2 to PLAYER collisions
02243 M3PL            = $D00B                           ; MISSILE3 to PLAYER collisions
02244 P3PL            = $D00F                           ; PLAYER3 to PLAYER collisions
02245 TRIG0           = $D010                           ; Joystick 0 trigger
02246 COLPM0          = $D012                           ; Color and brightness of PLAYER0
02247 COLPF0          = $D016                           ; Color and brightness of PLAYFIELD0
02248 PRIOR           = $D01B                           ; Priority selection register
02249 GRACTL          = $D01D                           ; Graphics control register
02250 HITCLR          = $D01E                           ; Clear collision register
02251 CONSOL          = $D01F                           ; Function keys register
02252 AUDF1           = $D200                           ; Audio channel 1 frequency
02253 AUDF2           = $D202                           ; Audio channel 2 frequency
02254 AUDC2           = $D203                           ; Audio channel 2 control
02255 AUDF3           = $D204                           ; Audio channel 3 frequency
02256 AUDC3           = $D205                           ; Audio channel 3 control
02257 AUDF4           = $D206                           ; Audio channel 4 frequency
02258 AUDC4           = $D207                           ; Audio channel 4 control
02259 AUDCTL          = $D208                           ; Audio control
02260 KBCODE          = $D209                           ; Keyboard code
02261 STIMER          = $D209                           ; Start POKEY timers
02262 RANDOM          = $D20A                           ; Random number generator
02263 IRQEN           = $D20E                           ; Interrupt request (IRQ) enable
02264 SKCTL           = $D20F                           ; Serial port control
02265 PORTA           = $D300                           ; Port A
02266 PACTL           = $D302                           ; Port A control
02267 DMACTL          = $D400                           ; Direct Memory Access (DMA) control
02268 DLIST           = $D402                           ; Display List pointer
02269 PMBASE          = $D407                           ; Player/Missile base address (high byte)
02270 CHBASE          = $D409                           ; Character set base address (high byte)
02271 WSYNC           = $D40A                           ; Wait for horizontal synchronization
02272 VCOUNT          = $D40B                           ; Vertical line counter
02273 NMIEN           = $D40E                           ; Non-maskable interrupt (NMI) enable
02274 ROMCHARSET      = $E000                           ; ROM character set
02275
02276 ;*******************************************************************************
02277 ;*                                                                             *
02278 ;*                           G A M E   S Y M B O L S                           *
02279 ;*                                                                             *
02280 ;*******************************************************************************
02281
02282 MISSIONLEVEL    = $62
02283 FKEYCODE        = $63
02284 ISDEMOMODE      = $64
02285 NEWTITLEPHR     = $65
02286 IDLECNTHI       = $66
02287 ISVBISYNC       = $67
02288 MEMPTR          = $68
02289
02290 DIVIDEND        = $6A
02291 JOYSTICKDELTA   = $6D
02292
02293
02294 VELOCITYLO      = $70
02295 NEWVELOCITY     = $71
02296 COUNT8          = $72
02297 EXPLLIFE        = $73
02298 CLOCKTIM        = $74
02299 DOCKSTATE       = $75
02300 COUNT256        = $76
02301 IDLECNTLO       = $77
02302 ZYLONUNITTIM    = $78
02303 MAXSPCOBJIND    = $79
02304 OLDMAXSPCOBJIND = $7A
02305 ISSTARBASESECT  = $7B
02306 ISTRACKCOMPON   = $7C
02307 DRAINSHIELDS    = $7D
02308 DRAINATTCOMP    = $7E
02309 ENERGYCNT       = $7F
02310 DRAINENGINES    = $80
02311 SHIELDSCOLOR    = $81
02312 PL3HIT          = $82
02313 PL4HIT          = $83
02314 OLDTRIG0        = $84
02315
02316 ISTRACKING      = $86
02317 BARRELNR        = $87
02318 LOCKONLIFE      = $88
02319 PLTRACKED       = $89
02320 HITBADNESS      = $8A
02321 REDALERTLIFE    = $8B
02322 WARPDEPRROW     = $8C
02323 WARPDEPRCOLUMN  = $8D
02324 WARPARRVROW     = $8E
02325 WARPARRVCOLUMN  = $8F
02326 CURRSECTOR      = $90
02327 WARPENERGY      = $91
02328 ARRVSECTOR      = $92
02329 HUNTSECTOR      = $93
02330 HUNTSECTCOLUMN  = $94
02331 HUNTSECTROW     = $95
02332 NEWZYLONDIST    = $96
02333 OLDZYLONDIST    = $9E
02334 HUNTTIM         = $9F
02335 BLIPCOLUMN      = $A0
02336 BLIPROW         = $A1
02337 BLIPCYCLECNT    = $A2
02338 ISINLOCKON      = $A3
02339 DIRLEN          = $A4
02340 PENROW          = $A5
02341 PENCOLUMN       = $A6
02342 CTRLDZYLON      = $A7
02343 ZYLONFLPAT0     = $A8
02344 ZYLONFLPAT1     = $A9
02345 MILESTTIM0      = $AA
02346 MILESTTIM1      = $AB
02347 MILESTVELINDZ0  = $AC
02348 MILESTVELINDZ1  = $AD
02349 MILESTVELINDX0  = $AE
02350 MILESTVELINDX1  = $AF
02351 MILESTVELINDY0  = $B0
02352 MILESTVELINDY1  = $B1
02353 ZYLONVELINDZ0   = $B2
02354 ZYLONVELINDZ1   = $B3
02355 ZYLONVELINDX0   = $B4
02356 ZYLONVELINDX1   = $B5
02357 ZYLONVELINDY0   = $B6
02358 ZYLONVELINDY1   = $B7
02359 ISBACKATTACK0   = $B8
02360 ISBACKATTACK1   = $B9
02361 ZYLONTIMX0      = $BA
02362 ZYLONTIMX1      = $BB
02363 ZYLONTIMY0      = $BC
02364 ZYLONTIMY1      = $BD
02365 TORPEDODELAY    = $BE
02366 ZYLONATTACKER   = $BF
02367 WARPSTATE       = $C0
02368 VELOCITYHI      = $C1
02369 TRAILDELAY      = $C2
02370 TRAILIND        = $C3
02371 WARPTEMPCOLUMN  = $C4
02372 WARPTEMPROW     = $C5
02373 VEERMASK        = $C6
02374 VICINITYMASK    = $C7
02375 JOYSTICKX       = $C8
02376 JOYSTICKY       = $C9
02377 KEYCODE         = $CA
02378 SCORE           = $CB
02379 SCOREDRANKIND   = $CD
02380 SCOREDCLASSIND  = $CE
02381 TITLELIFE       = $CF
02382 SHIPVIEW        = $D0
02383 TITLEPHR        = $D1
02384 BEEPFRQIND      = $D2
02385 BEEPREPEAT      = $D3
02386 BEEPTONELIFE    = $D4
02387 BEEPPAUSELIFE   = $D5
02388 BEEPPRIORITY    = $D6
02389 BEEPFRQSTART    = $D7
02390 BEEPLIFE        = $D8
02391 BEEPTOGGLE      = $D9
02392 NOISETORPTIM    = $DA
02393 NOISEEXPLTIM    = $DB
02394 NOISEAUDC2      = $DC
02395 NOISEAUDC3      = $DD
02396 NOISEAUDF1      = $DE
02397 NOISEAUDF2      = $DF
02398 NOISEFRQINC     = $E0
02399 NOISELIFE       = $E1
02400 NOISEZYLONTIM   = $E2
02401 NOISEHITLIFE    = $E3
02402 PL0SHAPOFF      = $E4
02403 PL1SHAPOFF      = $E5
02404 PL2SHAPOFF      = $E6
02405 PL3SHAPOFF      = $E7
02406 PL4SHAPOFF      = $E8
02407 PL0LIFE         = $E9
02408 PL1LIFE         = $EA
02409 PL2LIFE         = $EB
02410 PL3LIFE         = $EC
02411 PL4LIFE         = $ED
02412 PL0COLOR        = $EE
02413 PL1COLOR        = $EF
02414 PL2COLOR        = $F0
02415 PL3COLOR        = $F1
02416 PF0COLOR        = $F2
02417 PF1COLOR        = $F3
02418 PF2COLOR        = $F4
02419 PF3COLOR        = $F5
02420 BGRCOLOR        = $F6
02421 PF0COLORDLI     = $F7
02422 PF1COLORDLI     = $F8
02423 PF2COLORDLI     = $F9
02424 PF3COLORDLI     = $FA
02425 BGRCOLORDLI     = $FB
02426 DSPLST          = $0280
02427 PL4DATA         = $0300
02428 PL0DATA         = $0400
02429 PL1DATA         = $0500
02430 PL2DATA         = $0600
02431 PL3DATA         = $0700
02432 PFMEMROWLO      = $0800
02433 PFMEMROWHI      = $0864
02434 GCMEMMAP        = $08C9
02435 PANELTXT        = $0949
02436 VELOCD1         = $094B
02437 KILLCNTD1       = $0950
02438 ENERGYD1        = $0955
02439 TRACKC1         = $095A
02440 TRACKDIGIT      = $095C
02441 THETAC1         = $0960
02442 PHIC1           = $0966
02443 RANGEC1         = $096C
02444 GCTXT           = $0971
02445 GCWARPD1        = $097D
02446 GCTRGCNT        = $098D
02447 GCSTATPHO       = $0992
02448 GCSTATENG       = $0993
02449 GCSTATSHL       = $0994
02450 GCSTATCOM       = $0995
02451 GCSTATLRS       = $0996
02452 GCSTATRAD       = $0997
02453 GCSTARDAT       = $09A3
02454 ZPOSSIGN        = $09AD
02455 PL2ZPOSSIGN     = $09AF
02456 PL3ZPOSSIGN     = $09B0
02457 PL4ZPOSSIGN     = $09B1
02458 XPOSSIGN        = $09DE
02459 PL2XPOSSIGN     = $09E0
02460 PL3XPOSSIGN     = $09E1
02461 PL4XPOSSIGN     = $09E2
02462 YPOSSIGN        = $0A0F
02463 PL2YPOSSIGN     = $0A11
02464 PL3YPOSSIGN     = $0A12
02465 PL4YPOSSIGN     = $0A13
02466 ZPOSHI          = $0A40
02467 PL0ZPOSHI       = $0A40
02468 PL2ZPOSHI       = $0A42
02469 PL3ZPOSHI       = $0A43
02470 PL4ZPOSHI       = $0A44
02471 XPOSHI          = $0A71
02472 PL2XPOSHI       = $0A73
02473 PL3XPOSHI       = $0A74
02474 PL4XPOSHI       = $0A75
02475 YPOSHI          = $0AA2
02476 PL2YPOSHI       = $0AA4
02477 PL3YPOSHI       = $0AA5
02478 PL4YPOSHI       = $0AA6
02479 ZPOSLO          = $0AD3
02480 PL2ZPOSLO       = $0AD5
02481 PL3ZPOSLO       = $0AD6
02482 PL4ZPOSLO       = $0AD7
02483 XPOSLO          = $0B04
02484 PL2XPOSLO       = $0B06
02485 PL3XPOSLO       = $0B07
02486 PL4XPOSLO       = $0B08
02487 YPOSLO          = $0B35
02488 PL2YPOSLO       = $0B37
02489 PL3YPOSLO       = $0B38
02490 PL4YPOSLO       = $0B39
02491 ZVEL            = $0B66
02492 PL0ZVEL         = $0B66
02493 PL1ZVEL         = $0B67
02494 PL2ZVEL         = $0B68
02495 PL3ZVEL         = $0B69
02496 PL4ZVEL         = $0B6A
02497 XVEL            = $0B97
02498 PL0XVEL         = $0B97
02499 PL1XVEL         = $0B98
02500 PL2XVEL         = $0B99
02501 PL3XVEL         = $0B9A
02502 PL4XVEL         = $0B9B
02503 YVEL            = $0BC8
02504 PL0YVEL         = $0BC8
02505 PL1YVEL         = $0BC9
02506 PL2YVEL         = $0BCA
02507 PL3YVEL         = $0BCB
02508 PL4YVEL         = $0BCC
02509 PIXELROWNEW     = $0BF9
02510 PL0ROWNEW       = $0BF9
02511 PL1ROWNEW       = $0BFA
02512 PL2ROWNEW       = $0BFB
02513 PL3ROWNEW       = $0BFC
02514 PL4ROWNEW       = $0BFD
02515 PIXELCOLUMN     = $0C2A
02516 PL0COLUMN       = $0C2A
02517 PL1COLUMN       = $0C2B
02518 PL2COLUMN       = $0C2C
02519 PL3COLUMN       = $0C2D
02520 PL4COLUMN       = $0C2E
02521 PIXELROW        = $0C5B
02522 PL0ROW          = $0C5B
02523 PL1ROW          = $0C5C
02524 PL2ROW          = $0C5D
02525 PL3ROW          = $0C5E
02526 PL4ROW          = $0C5F
02527 PIXELBYTEOFF    = $0C8C
02528 PL0SHAPTYPE     = $0C8C
02529 PL1SHAPTYPE     = $0C8D
02530 PL2SHAPTYPE     = $0C8E
02531 PL3SHAPTYPE     = $0C8F
02532 PL4SHAPTYPE     = $0C90
02533 PIXELSAVE       = $0CBD
02534 PL0HEIGHT       = $0CBD
02535 PL1HEIGHT       = $0CBE
02536 PL2HEIGHT       = $0CBF
02537 PL3HEIGHT       = $0CC0
02538 PL4HEIGHT       = $0CC1
02539 PIXELBYTE       = $0CEE
02540 PL0HEIGHTNEW    = $0CEE
02541 PL1HEIGHTNEW    = $0CEF
02542 PL2HEIGHTNEW    = $0CF0
02543 PL3HEIGHTNEW    = $0CF1
02544 PL4HEIGHTNEW    = $0CF2
02545 TITLETXT        = $0D1F
02546 GCPFMEM         = $0D35
02547 MAPTO80         = $0DE9
02548 MAPTOBCD99      = $0EE9
02549 PFMEM           = $1000
02550
02551                 *= $A000
02552
02553 ;*******************************************************************************
02554 ;*                                                                             *
02555 ;*                G A M E   D A T A   ( P A R T   1   O F   2 )                *
02556 ;*                                                                             *
02557 ;*******************************************************************************
02558
02559 ;*** Number of space objects ***************************************************
02560
02561 NUMSPCOBJ.PL    = 5                               ; Number of PLAYER space objects
02562 NUMSPCOBJ.STARS = 12                              ; Number of PLAYFIELD space objects (stars)
02563 NUMSPCOBJ.NORM  = NUMSPCOBJ.PL+NUMSPCOBJ.STARS    ; Normal number of space objects
02564 NUMSPCOBJ.ALL   = 49                              ; Maximum number of space objects
02565
02566 ;*** PLAYER shape data offsets *************************************************
02567
02568 SHAP.TORPEDO    = $00                             ; Photon torpedo
02569 SHAP.ZFIGHTER   = $10                             ; Zylon fighter
02570 SHAP.STARBASEL  = $20                             ; Starbase (left part)
02571 SHAP.STARBASEC  = $30                             ; Starbase (center part)
02572 SHAP.STARBASER  = $40                             ; Starbase (right part)
02573 SHAP.TRANSVSSL  = $50                             ; Transfer vessel
02574 SHAP.METEOR     = $60                             ; Meteor
02575 SHAP.ZCRUISER   = $70                             ; Zylon cruiser
02576 SHAP.ZBASESTAR  = $80                             ; Zylon basestar
02577 SHAP.HYPERWARP  = $90                             ; Hyperwarp Target Marker
02578
02579 ;*** ROM character set constants ***********************************************
02580 ROM.SPC         = $00                             ; ROM character ' '
02581 ROM.DOT         = $0E                             ; ROM character '.'
02582 ROM.0           = $10                             ; ROM character '0'
02583 ROM.1           = $11                             ; ROM character '1'
02584 ROM.2           = $12                             ; ROM character '2'
02585 ROM.3           = $13                             ; ROM character '3'
02586 ROM.4           = $14                             ; ROM character '4'
02587 ROM.5           = $15                             ; ROM character '5'
02588 ROM.9           = $19                             ; ROM character '9'
02589 ROM.COLON       = $1A                             ; ROM character ':'
02590 ROM.A           = $21                             ; ROM character 'A'
02591 ROM.C           = $23                             ; ROM character 'C'
02592 ROM.D           = $24                             ; ROM character 'D'
02593 ROM.E           = $25                             ; ROM character 'E'
02594 ROM.G           = $27                             ; ROM character 'G'
02595 ROM.L           = $2C                             ; ROM character 'L'
02596 ROM.N           = $2E                             ; ROM character 'N'
02597 ROM.P           = $30                             ; ROM character 'P'
02598 ROM.R           = $32                             ; ROM character 'R'
02599 ROM.S           = $33                             ; ROM character 'S'
02600 ROM.T           = $34                             ; ROM character 'T'
02601 ROM.W           = $37                             ; ROM character 'W'
02602 ROM.Y           = $39                             ; ROM character 'Y'
02603
02604 ;*** Custom character set constants ********************************************
02605 CCS.COL1        = $40                             ; COLOR1 bits for text in GR1/2 text mode
02606 CCS.COL2        = $80                             ; COLOR2 bits for text in GR1/2 text mode
02607 CCS.COL3        = $C0                             ; COLOR3 bits for text in GR1/2 text mode
02608
02609 CCS.0           = 0                               ; Custom character '0'
02610 CCS.1           = 1                               ; Custom character '1'
02611 CCS.2           = 2                               ; Custom character '2'
02612 CCS.3           = 3                               ; Custom character '3'
02613 CCS.4           = 4                               ; Custom character '4'
02614 CCS.5           = 5                               ; Custom character '5'
02615 CCS.6           = 6                               ; Custom character '6'
02616 CCS.7           = 7                               ; Custom character '7'
02617 CCS.8           = 8                               ; Custom character '8'
02618 CCS.9           = 9                               ; Custom character '9'
02619 CCS.SPC         = 10                              ; Custom character ' '
02620 CCS.COLON       = 11                              ; Custom character ':'
02621 CCS.BORDERSW    = 12                              ; Custom character 'BORDER SOUTHWEST'
02622 CCS.E           = 13                              ; Custom character 'E'
02623 CCS.INF         = 14                              ; Custom character 'INFINITY'
02624 CCS.MINUS       = 15                              ; Custom character '-'
02625 CCS.PLUS        = 16                              ; Custom character '+'
02626 CCS.PHI         = 17                              ; Custom character 'PHI'
02627 CCS.V           = 18                              ; Custom character 'V'
02628 CCS.R           = 19                              ; Custom character 'R'
02629 CCS.THETA       = 20                              ; Custom character 'THETA'
02630 CCS.K           = 21                              ; Custom character 'K'
02631 CCS.T           = 22                              ; Custom character 'T'
02632 CCS.C           = 23                              ; Custom character 'C'
02633 CCS.BORDERS     = 24                              ; Custom character 'BORDER SOUTH'
02634 CCS.BORDERW     = 25                              ; Custom character 'BORDER WEST'
02635 CCS.CORNERSW    = 26                              ; Custom character 'CORNER SOUTHWEST'
02636 CCS.STARBASE    = 27                              ; Custom character 'STARBASE SECTOR'
02637 CCS.4ZYLONS     = 28                              ; Custom character '4-ZYLON SECTOR'
02638 CCS.3ZYLONS     = 29                              ; Custom character '3-ZYLON SECTOR'
02639 CCS.2ZYLONS     = 30                              ; Custom character '2-ZYLON SECTOR'
02640
02641 ;*** Custom character set ******************************************************
02642 ;
02643 ; 0        1        2        3        4        5        6        7
02644 ; ........ ........ ........ ........ ........ ........ ........ ........
02645 ; .####### ..##.... .####... .####... .##..... .####... .####... .#####..
02646 ; .#...### ...#.... ....#... ....#... .##..... .#...... .#..#... .#...#..
02647 ; .#...### ...#.... ....#... ....#... .##..... .#...... .#...... .....#..
02648 ; .#...### ...#.... .####... .#####.. .##.##.. .####... .#...... ...###..
02649 ; .#...### ..###... .#...... ....##.. .#####.. ....#... .######. ...#....
02650 ; .#...### ..###... .#...... ....##.. ....##.. ....#... .#....#. ...#....
02651 ; .####### ..###... .####... .#####.. ....##.. .####... .######. ...#....
02652 ;
02653 ; 8        9        10       11       12       13       14       15
02654 ; ........ ........ ........ ..###... #....... ........ ........ ........
02655 ; ..###... .#####.. ........ ..###... #....... ..####.. .##..##. ........
02656 ; ..#.#... .#...#.. ........ ..###... #....... ..#..... #..##..# ........
02657 ; ..#.#... .#...#.. ........ ........ #....... ..#..... #..##..# .######.
02658 ; .#####.. .#####.. ........ ........ #....... .####... #..##..# ........
02659 ; .##.##.. ....##.. ........ ..###... #....... .##..... .##..##. ........
02660 ; .##.##.. ....##.. ........ ..###... #....... .##..... ........ ........
02661 ; .#####.. ....##.. ........ ..###... ######## .#####.. ........ ........
02662 ;
02663 ; 16       17       18       19       20       21       22       23
02664 ; ........ ........ .##..##. ........ ........ ........ #######. ######..
02665 ; ...##... ...##... .##..##. .#####.. ...###.. .#...##. #..#..#. #...##..
02666 ; ...##... .######. .##..##. .#...#.. ..#####. .#...##. ...#.... #...##..
02667 ; ...##... ##.##.## .##..##. .#...#.. .##...## .#...#.. ...##... #.......
02668 ; .######. #..##..# .##..##. .#####.. .#.###.# .#####.. ...##... #.......
02669 ; ...##... ##.##.## ..#.##.. .##.#... .##...## .##..#.. ...##... #.......
02670 ; ...##... .######. ..###... .##.##.. ..#####. .##..##. ...##... #....#..
02671 ; ...##... ...##... ..##.... .##.##.. ...###.. .##..##. ...##... ######..
02672 ;
02673 ; 24       25       26       27       28       29       30
02674 ; ........ #....... ........ #....... #....... #....... #.......
02675 ; ........ #....... ........ #.#.#.#. #..##... #...###. #.##....
02676 ; ........ #....... ........ #..###.. #....... #....... #..##...
02677 ; ........ #....... ........ #.#####. #.##.##. #.###... #.#####.
02678 ; ........ #....... ........ #..###.. #....... #....... #..##...
02679 ; ........ #....... ........ #.#.#.#. #...##.. #..###.. #.##....
02680 ; ........ #....... ........ #....... #....... #....... #.......
02681 ; ######## #....... #....... ######## ######## ######## ########
02682
02683 CHARSET         .BYTE $00,$7F,$47,$47,$47,$47,$47,$7F ; Custom character '0'
02684                 .BYTE $00,$30,$10,$10,$10,$38,$38,$38 ; Custom character '1'
02685                 .BYTE $00,$78,$08,$08,$78,$40,$40,$78 ; Custom character '2'
02686                 .BYTE $00,$78,$08,$08,$7C,$0C,$0C,$7C ; Custom character '3'
02687                 .BYTE $00,$60,$60,$60,$6C,$7C,$0C,$0C ; Custom character '4'
02688                 .BYTE $00,$78,$40,$40,$78,$08,$08,$78 ; Custom character '5'
02689                 .BYTE $00,$78,$48,$40,$40,$7E,$42,$7E ; Custom character '6'
02690                 .BYTE $00,$7C,$44,$04,$1C,$10,$10,$10 ; Custom character '7'
02691                 .BYTE $00,$38,$28,$28,$7C,$6C,$6C,$7C ; Custom character '8'
02692                 .BYTE $00,$7C,$44,$44,$7C,$0C,$0C,$0C ; Custom character '9'
02693                 .BYTE $00,$00,$00,$00,$00,$00,$00,$00 ; Custom character ' '
02694                 .BYTE $38,$38,$38,$00,$00,$38,$38,$38 ; Custom character ':'
02695                 .BYTE $80,$80,$80,$80,$80,$80,$80,$FF ; Custom character 'BORDER SOUTHWEST'
02696                 .BYTE $00,$3C,$20,$20,$78,$60,$60,$7C ; Custom character 'E'
02697                 .BYTE $00,$66,$99,$99,$99,$66,$00,$00 ; Custom character 'INFINITY'
02698                 .BYTE $00,$00,$00,$7E,$00,$00,$00,$00 ; Custom character '-'
02699                 .BYTE $00,$18,$18,$18,$7E,$18,$18,$18 ; Custom character '+'
02700                 .BYTE $00,$18,$7E,$DB,$99,$DB,$7E,$18 ; Custom character 'PHI'
02701                 .BYTE $66,$66,$66,$66,$66,$2C,$38,$30 ; Custom character 'V'
02702                 .BYTE $00,$7C,$44,$44,$7C,$68,$6C,$6C ; Custom character 'R'
02703                 .BYTE $00,$1C,$3E,$63,$5D,$63,$3E,$1C ; Custom character 'THETA'
02704                 .BYTE $00,$46,$46,$44,$7C,$64,$66,$66 ; Custom character 'K'
02705                 .BYTE $FE,$92,$10,$18,$18,$18,$18,$18 ; Custom character 'T'
02706                 .BYTE $FC,$8C,$8C,$80,$80,$80,$84,$FC ; Custom character 'C'
02707                 .BYTE $00,$00,$00,$00,$00,$00,$00,$FF ; Custom character 'BORDER SOUTH'
02708                 .BYTE $80,$80,$80,$80,$80,$80,$80,$80 ; Custom character 'BORDER WEST'
02709                 .BYTE $00,$00,$00,$00,$00,$00,$00,$80 ; Custom character 'CORNER SOUTHWEST'
02710                 .BYTE $80,$AA,$9C,$BE,$9C,$AA,$80,$FF ; Custom character 'STARBASE SECTOR'
02711                 .BYTE $80,$98,$80,$B6,$80,$8C,$80,$FF ; Custom character '4-ZYLON SECTOR'
02712                 .BYTE $80,$8E,$80,$B8,$80,$9C,$80,$FF ; Custom character '3-CYCLON SECTOR'
02713                 .BYTE $80,$B0,$98,$BE,$98,$B0,$80,$FF ; Custom character '2-ZYLON SECTOR'
02714
02715 ;*** Header text of Long-Range Scan view (shares spaces with following header) *
02716 LRSHEADER       .BYTE $00,$00,$6C,$6F,$6E,$67,$00,$72 ; "  LONG RANGE SCAN"
02717                 .BYTE $61,$6E,$67,$65,$00,$73,$63,$61
02718                 .BYTE $6E
02719
02720 ;*** Header text of Aft view (shares spaces with following header) *************
02721 AFTHEADER       .BYTE $00,$00,$00,$00,$00,$00,$61,$66 ; "      AFT VIEW   "
02722                 .BYTE $74,$00,$76,$69,$65,$77,$00,$00
02723                 .BYTE $00
02724
02725 ;*** Header text of Galactic Chart view ****************************************
02726 GCHEADER        .BYTE $00,$00,$00,$67,$61,$6C,$61,$63 ; "   GALACTIC CHART   "
02727                 .BYTE $74,$69,$63,$00,$63,$68,$61,$72
02728                 .BYTE $74,$00,$00,$00
02729
02730 ;*** Display List of Galactic Chart view ***************************************
02731 DLSTGC          .BYTE $60                             ; BLK7
02732                 .BYTE $46,<GCHEADER,>GCHEADER         ; GR1 @ GCHEADER
02733                 .BYTE $F0                             ; BLK8 + DLI
02734                 .BYTE $47,<GCPFMEM,>GCPFMEM           ; GR2 @ GCPFMEM
02735                 .BYTE $07                             ; GR2
02736                 .BYTE $07                             ; GR2
02737                 .BYTE $07                             ; GR2
02738                 .BYTE $07                             ; GR2
02739                 .BYTE $07                             ; GR2
02740                 .BYTE $07                             ; GR2
02741                 .BYTE $07                             ; GR2
02742                 .BYTE $07                             ; GR2
02743                 .BYTE $80                             ; BLK1 + DLI
02744                 .BYTE $46,<TITLETXT,>TITLETXT         ; GR1 @ TITLETXT
02745                 .BYTE $46,<GCTXT,>GCTXT               ; GR1 @ GCTXT
02746                 .BYTE $06                             ; GR1
02747                 .BYTE $06                             ; GR1
02748                 .BYTE $41,<DSPLST,>DSPLST             ; JMP @ DSPLST
02749
02750 ;*******************************************************************************
02751 ;*                                                                             *
02752 ;*                              G A M E   C O D E                              *
02753 ;*                                                                             *
02754 ;*******************************************************************************
02755
02756 ;*******************************************************************************
02757 ;*                                                                             *
02758 ;*                                  INITCOLD                                   *
02759 ;*                                                                             *
02760 ;*                        Initialize game (Cold start)                         *
02761 ;*                                                                             *
02762 ;*******************************************************************************
02763
02764 ; DESCRIPTION
02765 ;
02766 ; Initializes the game, then continues into the game loop at GAMELOOP ($A1F3).
02767 ;
02768 ; There are four entry points to initialization:
02769 ;
02770 ; (1)  INITCOLD ($A14A) is entered at initial cartridge startup (cold start).
02771 ;      This initializes POKEY, resets the idle counter, sets the mission level
02772 ;      to NOVICE mission, and clears the function key code. POKEY is enabled to
02773 ;      receive keyboard input. Code execution continues into INITSELECT ($A15A)
02774 ;      below.
02775 ;
02776 ; (2)  INITSELECT ($A15A) is entered from GAMELOOP ($A1F3) after the SELECT
02777 ;      function key has been pressed. This loads the title phrase offset for the
02778 ;      copyright notice. Code execution continues into INITDEMO ($A15C) below. 
02779 ;
02780 ; (3)  INITDEMO ($A15C) is entered when the game switches into demo mode. This
02781 ;      loads the demo mode flag. Code execution continues into INITSTART ($A15E)
02782 ;      below.
02783 ;
02784 ; (4)  INITSTART ($A15E) is entered from GAMELOOP ($A1F3) after the START
02785 ;      function key has been pressed. This enqueues the new title phrase and
02786 ;      enables or disables demo mode, depending on the preloaded value.
02787 ;
02788 ; Initialization continues with the following steps: 
02789 ;
02790 ; (1)  Clear the custom chip registers and zero page game variables from
02791 ;      ISVBISYNC ($0067) on.
02792 ;
02793 ;      NOTE: Because of loop jamming there is a loop index overshoot. This
02794 ;      clears memory at $0067..$0166 instead of the game's zero page memory at
02795 ;      $0067..$00FB. However, this does no harm because memory at $0100..$0166
02796 ;      is - at this point in time - a yet unused part of the 6502 CPU stack
02797 ;      (memory addresses $0100..$01FF).
02798 ;
02799 ;      NOTE: At address $A175 a hack is necessary in the source code to force an
02800 ;      STA ISVBISYNC,X instruction with a 16-bit address operand, as opposed to
02801 ;      an 8-bit (zero page) address operand. The latter would be chosen by
02802 ;      virtually all 6502 assemblers, as ISVBISYNC ($0067) is located in the
02803 ;      zero page (memory addresses $0000..$00FF). The reason to force a 16-bit
02804 ;      address operand is the following: The instruction STA ISVBISYNC,X is used
02805 ;      in a loop which iterates the CPU's X register from 0 to 255 to clear
02806 ;      memory. By using this instruction with a 16-bit address operand
02807 ;      ("indexed, absolute" mode), memory at $0067..$0166 is cleared. Had the
02808 ;      code been using the same operation with an 8-bit address operand
02809 ;      ("indexed, zero page" mode), memory at $0067..$00FF would have been
02810 ;      cleared first, then the indexed address would have wrapped back to $0000
02811 ;      and cleared memory at $0000..$0066, thus effectively overwriting already
02812 ;      initialized memory locations.
02813 ;
02814 ; (2)  Initialize the 6502 CPU (reset the stack pointer, disable decimal mode).
02815 ;
02816 ; (3)  Clear game memory from $0200..$1FFF in subroutine CLRMEM ($AE0F).
02817 ;
02818 ; (4)  Set the address vectors of the IRQ, VBI, and DLI handlers.
02819 ;
02820 ; (5)  Enable input from Joystick 0.
02821 ;
02822 ; (6)  Enable Player/Missile graphics, providing a fifth PLAYER, and set
02823 ;      PLAYER-PLAYFIELD priority.
02824 ;
02825 ;      BUG (at $A1A6): The set PLAYER-PLAYFIELD priority arranges PLAYERs
02826 ;      (PL0..4) in front of the PLAYFIELD (PF0..4) in this specific order, from
02827 ;      front to back:
02828 ;
02829 ;          PL0 > PL1 > PL2 > PL3 > PL4 > PF0, PF1, PF2 > PF4 (BGR)
02830 ;
02831 ;      This makes sense as space objects represented by PLAYERs (for example,
02832 ;      Zylon ships, photon torpedoes, and meteors) move in front of the stars,
02833 ;      which are part of the PLAYFIELD. However, PLAYERs also move in front of
02834 ;      the cross hairs, which are also part of the PLAYFIELD. Suggested fix:
02835 ;      None, technically not possible.  
02836 ;
02837 ; (7)  Do more initialization in subroutine INITIALIZE ($B3BA).
02838 ;
02839 ; (8)  Set display to Front view.
02840 ;
02841 ; (9)  Show or hide the Control Panel Display (bottom text window) in subroutine
02842 ;      MODDLST ($ADF1), depending on the demo mode flag.
02843 ;
02844 ; (10) Initialize our starship's velocity equivalent to speed key '6'.
02845 ;
02846 ; (11) Enable the Display List.
02847 ;
02848 ; (12) Initialize the number of space objects to 16 (5 PLAYER space objects + 12
02849 ;      PLAYFIELD space objects (stars), counted 0..16).
02850 ;
02851 ; (13) Set the title phrase to the selected mission level in subroutine SETTITLE
02852 ;      ($B223).
02853 ;
02854 ; (14) Enable the IRQ, DLI, and VBI interrupts.
02855 ;
02856 ; Code execution continues into the game loop at GAMELOOP ($A1F3).
02857
02858 INITCOLD        LDA #0                  ;
02859                 STA SKCTL               ; POKEY: Initialization
02860                 STA IDLECNTHI           ; Reset idle counter
02861                 STA MISSIONLEVEL        ; Mission level := NOVICE mission
02862                 STA FKEYCODE            ; Clear function key code
02863                 LDA #$03                ; POKEY: Enable keyboard scan and debounce
02864                 STA SKCTL               ;
02865
02866 ;*** Entry point when SELECT function key was pressed **************************
02867 INITSELECT      LDY #$2F                ; Prep title phrase "COPYRIGHT ATARI 1979"
02868
02869 ;*** Entry point when game switches into demo mode *****************************
02870 INITDEMO        LDA #$FF                ; Prep demo mode flag
02871
02872 ;*** Entry point when START function key was pressed ***************************
02873 INITSTART       STY NEWTITLEPHR         ; Enqueue new title phrase
02874                 STA ISDEMOMODE          ; Store demo mode flag
02875
02876 ;*** More initialization *******************************************************
02877                 LDA #0                  ; Clear custom chip registers, zero page variables
02878                 TAX                     ;
02879 LOOP001         STA HPOSP0,X            ; Clear $D000..$D0FF (GTIA registers)
02880                 STA DMACTL,X            ; Clear $D400..$D4FF (ANTIC registers)
02881                 CPX #$0F                ;
02882                 BCS SKIP001             ;
02883                 STA AUDF1,X             ; Clear $D200..$D20E (POKEY registers)
02884
02885 SKIP001         STA PORTA,X             ; Clear $D300..$D3FF (PIA registers)
02886                                         ; Clear $0067..$0166 (zero page game variables)
02887                 .BYTE $9D               ; HACK: Force ISVBISYNC,X with 16-bit address
02888                 .WORD ISVBISYNC         ; (loop jamming)
02889                 INX                     ;
02890                 BNE LOOP001             ;
02891
02892                 DEX                     ; Reset 6502 CPU stack pointer
02893                 TXS                     ;
02894
02895                 CLD                     ; Clear 6502 CPU decimal mode
02896
02897                 LDA #$02                ; Clear $0200..$1FFF (game memory)
02898                 JSR CLRMEM              ;
02899
02900                 LDA #<IRQHNDLR          ; Set IRQ handler (VIMIRQ)
02901                 STA VIMIRQ              ;
02902                 LDA #>IRQHNDLR          ;
02903                 STA VIMIRQ+1            ;
02904
02905                 LDA #<VBIHNDLR          ; Set VBI and DLI handler (VVBLKI and VDSLST)
02906                 STA VVBLKI              ;
02907                 LDA #<DLSTHNDLR         ;
02908                 STA VDSLST              ;
02909                 LDA #>VBIHNDLR          ;
02910                 STA VVBLKI+1            ;
02911                 LDA #>DLSTHNDLR         ;
02912                 STA VDSLST+1            ;
02913
02914                 LDA #$04                ; PIA: Enable PORTA (Joystick 0)
02915                 STA PACTL               ;
02916                 LDA #$11                ; GTIA: Enable PLAYER4, prio: PLs > PFs > BGR (!)
02917                 STA PRIOR               ; (PLAYERs in front of stars - and cross hairs)
02918                 LDA #$03                ; GTIA: Enable DMA for PLAYERs and MISSILEs
02919                 STA GRACTL              ;
02920
02921                 JSR INITIALIZE          ; Init Display List, tables, Galactic Chart, etc.
02922
02923                 LDX #$0A                ; Set Front view
02924                 JSR SETVIEW             ;
02925
02926                 LDA ISDEMOMODE          ; If in/not in demo mode hide/show...
02927                 AND #$80                ; ...Control Panel Display (bottom text window)
02928                 TAY                     ;
02929                 LDX #$5F                ;
02930                 LDA #$08                ;
02931                 JSR MODDLST             ;
02932
02933                 LDA #32                 ; Init our starship's velocity (= speed key '6')
02934                 STA NEWVELOCITY         ;
02935
02936                 LDA #<DSPLST            ; ANTIC: Set Display List
02937                 STA DLIST               ;
02938                 LDA #>DSPLST            ;
02939                 STA DLIST+1             ;
02940
02941                 LDA #$3E                ; ANTIC: Enable Display List DMA, single-line PM
02942                 STA DMACTL              ; resolution, PM DMA, normal-width PLAYFIELD
02943
02944                 LDA #0                  ; ANTIC: Set PM memory base address
02945                 STA PMBASE              ;
02946
02947                 LDA #NUMSPCOBJ.NORM-1   ; Set normal number of space objects
02948                 STA MAXSPCOBJIND        ; (5 PLAYER spc objs + 12 PLAYFIELD spc objs (stars))
02949
02950                 LDX MISSIONLEVEL        ; Set title phrase
02951                 LDY MISSIONPHRTAB,X     ; NOVICE, PILOT, WARRIOR, or COMMANDER MISSION
02952                 JSR SETTITLE            ;
02953
02954                 LDA #$40                ; POKEY: Enable keyboard interrupt (IRQ)
02955                 STA IRQEN               ;
02956
02957                 CLI                     ; Enable all IRQs
02958
02959                 LDA #$C0                ; ANTIC: Enable DLI and VBI
02960                 STA NMIEN               ;
02961
02962 ;*******************************************************************************
02963 ;*                                                                             *
02964 ;*                                  GAMELOOP                                   *
02965 ;*                                                                             *
02966 ;*******************************************************************************
02967
02968 ; DESCRIPTION
02969 ;
02970 ; The game loop is the main part of the game. It is basically an infinite loop
02971 ; that collects input, computes the game state, and updates the display. It
02972 ; executes the following steps:
02973 ;
02974 ; (1)  Synchronize the start of the game loop with the vertical blank phase of
02975 ;      the TV beam, which flagged by the Vertical Blank Interrupt handler
02976 ;      VBIHNDLR ($A6D1). This prevents screen flicker while the PLAYFIELD is
02977 ;      redrawn at the beginning of the game loop, because during the vertical
02978 ;      blank phase the TV beam is turned off and nothing is rendered on the TV
02979 ;      display. 
02980 ;
02981 ; (2)  Erase all PLAYFIELD space objects (stars, explosion fragments) from the
02982 ;      PLAYFIELD that were drawn in the previous game loop iteration.
02983 ;
02984 ; (3)  Draw the updated PLAYFIELD space objects (stars, explosion fragments)
02985 ;      into the PLAYFIELD (skip this if in hyperspace).
02986 ;
02987 ; (4)  If the idle counter has reached its trigger value then clear the center
02988 ;      of the PLAYFIELD, an 8 x 2 pixel rectangle with a top-left position at
02989 ;      pixel column number 76 and pixel row number 49 (?).
02990 ;
02991 ; (5)  Clear all PLAYER shapes.
02992 ;
02993 ; (6)  Update the vertical position of all PLAYERs and update all PLAYER shapes.
02994 ;
02995 ; (7)  Update the horizontal position of all PLAYERs.
02996 ;
02997 ; (8)  Rotate the position vector of all space objects horizontally and
02998 ;      vertically, according to the saved joystick position (skip this if in
02999 ;      Galactic Chart view) using subroutine ROTATE ($B69B).
03000 ;
03001 ; (9)  Move our starship forward in space. Our starship is always located at the
03002 ;      center of the game's 3D coordinate system, so all space objects are moved
03003 ;      along the z-axis toward our starship by subtracting a displacement from
03004 ;      their z-coordinate. The amount of the displacement depends on our
03005 ;      starship's velocity.
03006 ;
03007 ;      BUG (at $A3C1): This operation is not applied to Photon torpedoes (?).
03008 ;      Suggested fix: Remove LDA PL0SHAPTYPE,X and BEQ SKIP011. 
03009 ;
03010 ; (10) Add the proper velocity vector of all space objects to their position
03011 ;      vector (except for stars, which do not have any proper motion).
03012 ;
03013 ;      BUG (at $A419): The correct maximum loop index is NUMSPCOBJ.ALL*3 = 147
03014 ;      instead of 144. Suggested fix: Replace CMP #144 with CMP #147.
03015 ;
03016 ; (11) Correct the position vector components (coordinates) of all PLAYER space
03017 ;      objects if they have over- or underflowed during the calculations of the
03018 ;      previous steps.
03019 ;
03020 ; (12) Calculate the perspective projection of the position vectors of all space
03021 ;      objects and from that their pixel row and column number (applies to Front
03022 ;      and Aft view) using subroutines PROJECTION ($AA21), SCREENCOLUMN ($B6FB),
03023 ;      and SCREENROW ($B71E). If a space object (star, explosion fragment) moved
03024 ;      offscreen then a new space object is automatically created in subroutine
03025 ;      SCREENCOLUMN ($B6FB).
03026 ;
03027 ; (13) Handle hyperwarp marker selection in the Galactic Chart view in
03028 ;      subroutine SELECTWARP ($B162).
03029 ;
03030 ; (14) If in Long-Range Scan view, compute the pixel column number and the pixel
03031 ;      row number of all PLAYFIELD space objects (stars, explosion fragments) on
03032 ;      the plane established by the z and x axis of the 3D coordinate system
03033 ;      using subroutines SCREENCOLUMN ($B6FB) and SCREENROW ($B71E). Our
03034 ;      starship's shape is drawn using subroutine DRAWLINES ($A76F). If the
03035 ;      Long-Range Scan is OK then PLAYFIELD space object pixel numbers are
03036 ;      computed and drawn. This is skipped if the Long-Range Scan is destroyed. 
03037 ;
03038 ; (15) Update all PLAYER shapes, heights, and colors (see detailed description
03039 ;      below).
03040 ;
03041 ; (16) Flash a red alert when leaving hyperspace into a sector containing Zylon
03042 ;      ships by setting appropriate colors to PLAYFIELD2 and BACKGROUND.
03043 ;
03044 ; (17) Update the color of all PLAYFIELD space objects (stars, explosion
03045 ;      fragments). The color calculation is similar to that of the PLAYER color
03046 ;      calculation in (15). It also computes a range index and uses the same
03047 ;      color lookup table FOURCOLORPIXEL ($BA90). If a star in the Aft view
03048 ;      became too distant (z-coordinate < -$F000 (-4096) <KM>) its position is
03049 ;      re-initialized in subroutine INITPOSVEC ($B764).
03050 ;
03051 ; (18) If in demo mode skip input handling and jump directly to function key
03052 ;      handling (28).
03053 ;
03054 ; (19) Handle keyboard input in subroutine KEYBOARD ($AFFE).
03055 ;
03056 ; (20) Handle joystick input. Store the current joystick directions in JOYSTICKX
03057 ;      ($C8) and JOYSTICKY ($C9).
03058 ;
03059 ; (21) Check if our starship's photon torpedoes have hit a target in subroutine
03060 ;      COLLISION ($AF3D). This subroutine triggers a game over if all Zylon
03061 ;      ships have been destroyed.
03062 ;
03063 ; (22) Handle the joystick trigger in subroutine TRIGGER ($AE29).
03064 ;
03065 ; (23) Handle the Attack Computer and Tracking Computer. If the Attack Computer
03066 ;      is neither destroyed nor switched off then execute the following steps:
03067 ;
03068 ;      o   Update the Attack Computer Display's blip and lock-on markers in
03069 ;          subroutine UPDATTCOMP ($A7BF) (if in Front view).
03070 ;
03071 ;      o   Update the tracking index of the currently tracked PLAYER space
03072 ;          object. If a Zylon ship is tracked, then make sure to always track
03073 ;          the Zylon ship that launched the last Zylon photon torpedo. If this
03074 ;          Zylon ship is not alive then track the other Zylon ship - if alive.
03075 ;
03076 ;      o   If the Tracking Computer is on then switch to the view that shows the
03077 ;          tracked PLAYER space object by emulating pressing the 'F' (Front
03078 ;          view) or 'A' (Aft view) key (only if in Front or Aft view).
03079 ;
03080 ; (24) Handle docking at a starbase in subroutine DOCKING ($ACE6).
03081 ;
03082 ; (25) Handle maneuvering both of our starship's photon torpedoes, the single
03083 ;      Zylon photon torpedo, and the attacking Zylon ships in subroutine
03084 ;      MANEUVER ($AA79). This subroutine also automatically creates meteors and
03085 ;      new Zylon ships.
03086 ;
03087 ; (26) Check if our starship was hit by a Zylon photon torpedo (skip this if in
03088 ;      a starbase sector): Its x, y, and z coordinates must be within a range of
03089 ;      -($0100)..+$00FF (-256..+255) <KM> of our starship.
03090 ;
03091 ; (27) If our starship was hit then execute the following steps:
03092 ;
03093 ;      o   Damage or destroy one of our starship's subsystems in subroutine
03094 ;          DAMAGE ($AEE1).
03095 ;
03096 ;      o   Trigger an explosion in subroutine INITEXPL ($AC6B), 
03097 ;
03098 ;      o   Store the severity of the hit.
03099 ;
03100 ;      o   End the lifetime of the Zylon photon torpedo.
03101 ;
03102 ;      o   Subtract 100 energy units for being hit by the Zylon photon torpedo
03103 ;          in subroutine DECENERGY ($B86F). 
03104 ;
03105 ;      o   Trigger the noise sound pattern SHIELD EXPLOSION in subroutine NOISE
03106 ;          ($AEA8). 
03107 ;
03108 ;      If the Shields were down during the hit, our starship is destroyed.
03109 ;      Execute the following steps:
03110 ;
03111 ;      o   Switch to Front view.
03112 ;
03113 ;      o   Flash the title phrase "SHIP DESTROYED BY ZYLON FIRE".
03114 ;
03115 ;      o   Add the mission bonus to the internal game score in subroutine
03116 ;          GAMEOVER ($B10A).
03117 ;
03118 ;      o   Hide the Control Panel Display (bottom text window) in subroutine
03119 ;          MODDLST ($ADF1).
03120 ;
03121 ;      o   Clear the PLAYFIELD in subroutine CLRPLAYFIELD ($AE0D).
03122 ;
03123 ;      o   Enable the STARSHIP EXPLOSION noise. 
03124 ;
03125 ; (28) Handle the function keys START and SELECT. If SELECT has been pressed
03126 ;      cycle through the next of the 4 mission levels. If either START or SELECT
03127 ;      have been pressed, reset the idle counter, then jump to the corresponding
03128 ;      game initialization subroutines INITSTART ($A15E) or INITSELECT ($A15A),
03129 ;      respectively. 
03130 ;
03131 ; (29) Update the Control Panel Display in subroutine UPDPANEL ($B804).
03132 ;
03133 ; (30) Handle hyperwarp in subroutine HYPERWARP ($A89B).
03134 ;
03135 ; (31) Update the text in the title line in subroutine UPDTITLE ($B216).
03136 ;
03137 ; (32) Move Zylon units, decrease lifetime of photon torpedoes, elapse game
03138 ;      time, etc. in subroutine FLUSHGAMELOOP ($B4E4). This subroutine also
03139 ;      triggers a game over if our starship's energy is zero.
03140 ;
03141 ; (33) Jump back to the start of the game loop for the next game loop iteration.
03142
03143 L.HEIGHTCNT     = $6A                   ; Height counter during copying a PLAYER shape
03144 L.ZPOSOFF       = $6E                   ; Offset to z-coordinate
03145 L.VELOCITYHI    = $6B                   ; Velocity vector component (high byte)
03146 L.VECCOMPIND    = $6A                   ; Position vector component index. Used values are:
03147                                         ;   0 -> z-component
03148                                         ;   1 -> x-component
03149                                         ;   2 -> y-component
03150 L.RANGEINDEX    = $6A                   ; Range index for space object, computed from the
03151                                         ; distance to our starship. Used to pick the shape
03152                                         ; cell index of the PLAYERs shape data and shape
03153                                         ; height. Used values are: 0..15.
03154 L.FOURCOLORPIX  = $6A                   ; 1-byte bit pattern for 4 pixels of same color
03155 L.COLORMASK     = $6B                   ; Color/brightness to modify PLAYER color
03156
03157 ;*** (1) Synchronize game loop with execution of VBI ***************************
03158 GAMELOOP        LDA ISVBISYNC           ; Wait for execution of VBI
03159                 BEQ GAMELOOP            ;
03160
03161                 LDA #0                  ; VBI is executed, clear VBI sync flag
03162                 STA ISVBISYNC           ;
03163
03164 ;*** (2) Erase PLAYFIELD space objects (stars, explosion fragments) ************
03165                 LDA OLDMAXSPCOBJIND     ; Skip if no space objects in use
03166                 BEQ SKIP002             ;
03167
03168                 LDX #NUMSPCOBJ.PL-1     ; Loop over all PLAYFIELD space objs (X index > 4)
03169 LOOP002         INX                     ;
03170                 LDY PIXELROW,X          ; Load pixel row number of PLAYFIELD space object
03171
03172                 LDA PFMEMROWLO,Y        ; Point MEMPTR to start of pixel's row...
03173                 STA MEMPTR              ; ...in PLAYFIELD memory
03174                 LDA PFMEMROWHI,Y        ;
03175                 STA MEMPTR+1            ;
03176
03177                 LDY PIXELBYTEOFF,X      ; Get within-row-offset to byte with space obj pixel
03178                 LDA PIXELSAVE,X         ; Load saved byte
03179                 STA (MEMPTR),Y          ; Restore byte of PLAYFIELD memory
03180
03181                 CPX OLDMAXSPCOBJIND     ;
03182                 BCC LOOP002             ; Next PLAYFIELD space object
03183
03184                 LDA #0                  ; Clear number of space objects
03185                 STA OLDMAXSPCOBJIND     ;
03186
03187 ;*** (3) Draw PLAYFIELD space objects (stars, explosion fragments) *************
03188 SKIP002         LDA WARPSTATE           ; Skip during hyperspace
03189                 BMI SKIP003             ;
03190
03191                 LDX MAXSPCOBJIND        ; Update number of space objects
03192                 STX OLDMAXSPCOBJIND     ;
03193
03194 LOOP003         LDA PIXELROWNEW,X       ; Loop over all PLAYFIELD space objs (X index > 4)
03195                 STA PIXELROW,X          ; Update pixel row number of PLAYFIELD space object
03196
03197                 TAY                     ;
03198                 LDA PFMEMROWLO,Y        ; Point MEMPTR to start of pixel's row...
03199                 STA MEMPTR              ; ...in PLAYFIELD memory
03200                 LDA PFMEMROWHI,Y        ;
03201                 STA MEMPTR+1            ;
03202
03203                 LDA PIXELCOLUMN,X       ; Convert pixel column number to within-row-offset
03204                 LSR A                   ; ...of byte with space obj pixel (4 pixels = 1 byte)
03205                 LSR A                   ;
03206                 STA PIXELBYTEOFF,X      ; Store within-row-offset
03207
03208                 TAY                     ;
03209                 LDA (MEMPTR),Y          ; Load pixel's byte from PLAYFIELD memory
03210                 STA PIXELSAVE,X         ; Save it (for restoring it in next game loop)
03211                 ORA PIXELBYTE,X         ; Blend with pixel's color bit-pattern
03212                 STA (MEMPTR),Y          ; Store byte in PLAYFIELD memory
03213
03214                 DEX                     ;
03215                 CPX #NUMSPCOBJ.PL-1     ;
03216                 BNE LOOP003             ; Next PLAYFIELD space object
03217
03218 ;*** (4) Clear PLAYFIELD center if idle counter is up (?) **********************
03219                                         ; PLAYFIELD addresses of...
03220 PFMEM.C76R49    = PFMEM+49*40+76/4      ; ...pixel column number 76, row number 49
03221 PFMEM.C80R49    = PFMEM+49*40+80/4      ; ...pixel column number 80, row number 49
03222 PFMEM.C76R50    = PFMEM+50*40+76/4      ; ...pixel column number 76, row number 50
03223 PFMEM.C80R50    = PFMEM+50*40+80/4      ; ...pixel column number 80, row number 50
03224
03225 SKIP003         LDA IDLECNTHI           ; Skip if idle counter not negative
03226                 BPL SKIP004             ;
03227
03228                 LDA #0                  ; Clear pixels of 8 x 2 pixel rectangle...
03229                 STA PFMEM.C76R50        ; ...@ column number 76, row number 49 (?)
03230                 STA PFMEM.C80R50        ;
03231                 STA PFMEM.C80R49        ;
03232                 STA PFMEM.C76R49        ;
03233
03234 ;*** (5) Clear all PLAYER shapes ***********************************************
03235 SKIP004         LDA #0                  ; Clear shape of PLAYER4
03236                 LDY PL4ROW              ;
03237                 LDX PL4HEIGHT           ;
03238 LOOP004         STA PL4DATA,Y           ;
03239                 INY                     ;
03240                 DEX                     ;
03241                 BPL LOOP004             ;
03242
03243                 LDY PL3ROW              ; Clear shape of PLAYER3
03244                 LDX PL3HEIGHT           ;
03245 LOOP005         STA PL3DATA,Y           ;
03246                 INY                     ;
03247                 DEX                     ;
03248                 BPL LOOP005             ;
03249
03250                 LDY PL2ROW              ; Clear shape of PLAYER2
03251                 LDX PL2HEIGHT           ;
03252 LOOP006         STA PL2DATA,Y           ;
03253                 INY                     ;
03254                 DEX                     ;
03255                 BPL LOOP006             ;
03256
03257                 LDY PL1ROW              ; Clear shape of PLAYER1
03258                 LDX PL1HEIGHT           ;
03259 LOOP007         STA PL1DATA,Y           ;
03260                 INY                     ;
03261                 DEX                     ;
03262                 BPL LOOP007             ;
03263
03264                 LDY PL0ROW              ; Clear shape of PLAYER0
03265                 LDX PL0HEIGHT           ;
03266 LOOP008         STA PL0DATA,Y           ;
03267                 INY                     ;
03268                 DEX                     ;
03269                 BPL LOOP008             ;
03270
03271 ;*** (6) Update PLAYER vertical positions and update PLAYER shapes *************
03272                 LDA PL4SHAPTYPE         ; CARRY := PLAYER4 a PHOTON TORPEDO (shape type 0)?
03273                 CMP #1                  ;
03274                 LDY PL4SHAPOFF          ; Load PLAYER4 shape data offset
03275
03276                 LDX PL4ROWNEW           ; Update vertical position of PLAYER4
03277                 STX PL4ROW              ;
03278
03279                 LDA PL4HEIGHTNEW        ; Update PLAYER4 shape height
03280                 STA L.HEIGHTCNT         ;
03281                 STA PL4HEIGHT           ;
03282
03283 LOOP009         LDA PLSHAP1TAB,Y        ; Load PLAYER4 shape byte from shape data table
03284                 BCS SKIP005             ; Skip if PLAYER4 not PHOTON TORPEDO (shape type 0)
03285                 AND RANDOM              ; AND random bits to shape byte
03286 SKIP005         STA PL4DATA,X           ; Store shape byte in PLAYER4 data area
03287                 INY                     ;
03288                 INX                     ;
03289                 DEC L.HEIGHTCNT         ;
03290                 BPL LOOP009             ; Next row of PLAYER4 shape
03291
03292                 LDA PL3SHAPTYPE         ; Repeat above with PLAYER3
03293                 CMP #1                  ;
03294                 LDY PL3SHAPOFF          ;
03295                 LDX PL3ROWNEW           ;
03296                 STX PL3ROW              ;
03297                 LDA PL3HEIGHTNEW        ;
03298                 STA L.HEIGHTCNT         ;
03299                 STA PL3HEIGHT           ;
03300 LOOP010         LDA PLSHAP1TAB,Y        ;
03301                 BCS SKIP006             ;
03302                 AND RANDOM              ;
03303 SKIP006         STA PL3DATA,X           ;
03304                 INX                     ;
03305                 INY                     ;
03306                 DEC L.HEIGHTCNT         ;
03307                 BPL LOOP010             ;
03308
03309                 LDA PL2SHAPTYPE         ; Repeat above with PLAYER2
03310                 CMP #1                  ;
03311                 LDY PL2SHAPOFF          ;
03312                 LDX PL2ROWNEW           ;
03313                 STX PL2ROW              ;
03314                 LDA PL2HEIGHTNEW        ;
03315                 STA L.HEIGHTCNT         ;
03316                 STA PL2HEIGHT           ;
03317 LOOP011         LDA PLSHAP1TAB,Y        ;
03318                 BCS SKIP007             ;
03319                 AND RANDOM              ;
03320 SKIP007         STA PL2DATA,X           ;
03321                 INX                     ;
03322                 INY                     ;
03323                 DEC L.HEIGHTCNT         ;
03324                 BPL LOOP011             ;
03325
03326                 LDY PL1SHAPOFF          ; Repeat above with PLAYER1 (without torpedo part)
03327                 LDX PL1ROWNEW           ;
03328                 STX PL1ROW              ;
03329                 LDA PL1HEIGHTNEW        ;
03330                 STA L.HEIGHTCNT         ;
03331                 STA PL1HEIGHT           ;
03332 LOOP012         LDA PLSHAP2TAB,Y        ;
03333                 STA PL1DATA,X           ;
03334                 INX                     ;
03335                 INY                     ;
03336                 DEC L.HEIGHTCNT         ;
03337                 BPL LOOP012             ;
03338
03339                 LDY PL0SHAPOFF          ; Repeat above with PLAYER0 (without torpedo part)
03340                 LDX PL0ROWNEW           ;
03341                 STX PL0ROW              ;
03342                 LDA PL0HEIGHTNEW        ;
03343                 STA L.HEIGHTCNT         ;
03344                 STA PL0HEIGHT           ;
03345 LOOP013         LDA PLSHAP2TAB,Y        ;
03346                 STA PL0DATA,X           ;
03347                 INX                     ;
03348                 INY                     ;
03349                 DEC L.HEIGHTCNT         ;
03350                 BPL LOOP013             ;
03351
03352 ;*** (7) Update PLAYER horizontal positions ************************************
03353                 LDA PL0COLUMN           ; Update horizontal position of PLAYER0
03354                 STA HPOSP0              ;
03355                 LDA PL1COLUMN           ; Update horizontal position of PLAYER1
03356                 STA HPOSP1              ;
03357                 LDA PL2COLUMN           ; Update horizontal position of PLAYER2
03358                 STA HPOSP2              ;
03359                 LDA PL3COLUMN           ; Update horizontal position of PLAYER3
03360                 STA HPOSP3              ;
03361                 LDA PL4COLUMN           ; Update horizontal position of PLAYER4
03362                 STA HPOSM3              ;
03363                 CLC                     ;
03364                 ADC #2                  ;
03365                 STA HPOSM2              ;
03366                 ADC #2                  ;
03367                 STA HPOSM1              ;
03368                 ADC #2                  ;
03369                 STA HPOSM0              ;
03370
03371 ;*** (8) Rotate space objects horizontally and vertically **********************
03372                 BIT SHIPVIEW            ; Skip if in Galactic Chart view
03373                 BMI SKIP009             ;
03374
03375 ;*** Rotate horizontally *******************************************************
03376                 LDA JOYSTICKX           ; Skip if joystick centered horizontally
03377                 BEQ SKIP008             ;
03378
03379                 STA JOYSTICKDELTA       ; Save JOYSTICKX (used in subroutine ROTATE)
03380                 LDY MAXSPCOBJIND        ; Loop over all space objects in use
03381 LOOP014         STY L.ZPOSOFF           ; Save offset to z-coordinate
03382                 CLC                     ;
03383
03384                 TYA                     ;
03385                 TAX                     ; X := offset to z-coordinate
03386                 ADC #NUMSPCOBJ.ALL      ;
03387                 TAY                     ; Y := offset to x-coordinate
03388                 JSR ROTATE              ; Calc new x-coordinate (horizontal rot @ y-axis)
03389
03390                 TYA                     ;
03391                 TAX                     ; X := offset to x-coordinate
03392                 LDY L.ZPOSOFF           ; Y := offset to z-coordinate
03393                 JSR ROTATE              ; Calc new z-coordinate (horizontal rot @ y-axis)
03394                 DEY                     ;
03395                 BPL LOOP014             ; Next space object
03396
03397 ;*** Rotate vertically *********************************************************
03398 SKIP008         LDA JOYSTICKY           ; Skip if joystick centered vertically
03399                 BEQ SKIP009             ;
03400
03401                 STA JOYSTICKDELTA       ; Save JOYSTICKY (used in subroutine ROTATE)
03402                 LDY MAXSPCOBJIND        ; Loop over all space objects in use
03403 LOOP015         STY L.ZPOSOFF           ; Save offset to z-coordinate
03404                 CLC                     ;
03405
03406                 TYA                     ;
03407                 TAX                     ; X := offset to z-coordinate
03408                 ADC #NUMSPCOBJ.ALL*2    ;
03409                 TAY                     ; Y := offset to y-coordinate
03410                 JSR ROTATE              ; Calc new y-coordinate (vertical rot @ x-axis)
03411
03412                 TYA                     ;
03413                 TAX                     ; X := offset to y-coordinate
03414                 LDY L.ZPOSOFF           ; Y := offset to z-coordinate
03415                 JSR ROTATE              ; Calc new z-coordinate (vertical rot @ x-axis)
03416                 DEY                     ;
03417                 BPL LOOP015             ; Next space object
03418
03419 ;*** (9) Move all space objects along z-axis (toward our starship) *************
03420 SKIP009         LDX MAXSPCOBJIND        ; Loop over all space objects in use
03421 LOOP016         CPX #NUMSPCOBJ.PL       ; Skip if PLAYFIELD space object (X index > 4)
03422                 BCS SKIP010             ;
03423
03424                 LDA PL0SHAPTYPE,X       ; Skip if next PLAYER space obj is PHOTON TORPEDO (!)
03425                 BEQ SKIP011             ;
03426
03427 SKIP010         SEC                     ; New z-coordinate := old z-coordinate -
03428                 LDA ZPOSLO,X            ; ...our starship's velocity
03429                 SBC VELOCITYLO          ; (signed 24-bit subtraction)
03430                 STA ZPOSLO,X            ;
03431                 LDA ZPOSHI,X            ;
03432                 SBC VELOCITYHI          ;
03433                 STA ZPOSHI,X            ;
03434                 LDA ZPOSSIGN,X          ;
03435                 SBC #0                  ;
03436                 STA ZPOSSIGN,X          ;
03437
03438 SKIP011         DEX                     ;
03439                 BPL LOOP016             ; Next space object
03440
03441 ;*** (10) Add space object's velocity vector to space object's position vector *
03442                 LDX MAXSPCOBJIND        ; Loop over all space objects in use
03443 LOOP017         CPX #NUMSPCOBJ.NORM-1   ; Skip if space object is star (X index 5..16)...
03444                 BNE SKIP012             ; ...because stars don't move by themselves
03445                 LDX #4                  ;
03446
03447 SKIP012         TXA                     ;
03448 LOOP018         TAY                     ; Loop over all 3 coordinates
03449
03450                 LDA #0                  ; Expand 8-bit velocity vector component to 16-bit:
03451                 STA L.VELOCITYHI        ; ...16-bit velocity (high byte) = L.VELOCITYHI := 0
03452                 LDA ZVEL,Y              ; ...16-bit velocity (low byte)  = A := ZVEL,Y
03453                 BPL SKIP013             ; Skip if 16-bit velocity >= 0 (positive)
03454
03455                 EOR #$7F                ; 16-bit velocity < 0 (negative)...
03456                 CLC                     ; ...calculate two's-complement of 16-bit velocity
03457                 ADC #1                  ;
03458                 BCS SKIP013             ;
03459                 DEC L.VELOCITYHI        ;
03460
03461 SKIP013         CLC                     ; New coordinate := old coordinate + 16-bit velocity
03462                 ADC ZPOSLO,Y            ; (signed 24-bit addition)
03463                 STA ZPOSLO,Y            ;
03464                 LDA ZPOSHI,Y            ;
03465                 ADC L.VELOCITYHI        ;
03466                 STA ZPOSHI,Y            ;
03467                 LDA ZPOSSIGN,Y          ;
03468                 ADC L.VELOCITYHI        ;
03469                 STA ZPOSSIGN,Y          ;
03470
03471                 TYA                     ;
03472                 CLC                     ;
03473                 ADC #NUMSPCOBJ.ALL      ;
03474                 CMP #144                ; (!)
03475                 BCC LOOP018             ; Next coordinate
03476
03477                 DEX                     ;
03478                 BPL LOOP017             ; Next space object
03479
03480 ;*** (11) Correct over/underflow of PLAYER space objects' position vector ******
03481                 LDY #NUMSPCOBJ.PL-1     ;
03482 LOOP019         TYA                     ; Loop over all PLAYER space objects (X index < 5)
03483                 TAX                     ;
03484
03485                 LDA #2                  ; Loop over all 3 coordinates
03486                 STA L.VECCOMPIND        ;
03487
03488 LOOP020         LDA ZPOSSIGN,X          ; Load sign of coordinate
03489                 CMP #2                  ;
03490                 BCC SKIP015             ; Skip if sign = 0 (negative) or 1 (positive)
03491
03492                 ASL A                   ; SUMMARY: Space object out-of-bounds correction
03493                 LDA #0                  ; If new coordinate > +65535 <KM> subtract 256 <KM>
03494                 STA ZPOSSIGN,X          ; ...until new coordinate <= +65535 <KM>
03495                 BCS SKIP014             ; If new coordinate < -65536 <KM> add 256 <KM>
03496                 INC ZPOSSIGN,X          ; ...until new coordinate >= -65536 <KM>
03497                 EOR #$FF                ;
03498 SKIP014         STA ZPOSHI,X            ;
03499
03500 SKIP015         TXA                     ;
03501                 CLC                     ;
03502                 ADC #NUMSPCOBJ.ALL      ;
03503                 TAX                     ;
03504                 DEC L.VECCOMPIND        ;
03505                 BPL LOOP020             ; Next coordinate
03506
03507                 DEY                     ;
03508                 BPL LOOP019             ; Next space object
03509
03510 ;*** (12) Calc perspective projection of space objects *************************
03511                 LDA SHIPVIEW            ; Skip if in Long-Range Scan or Galactic Chart view
03512                 CMP #$02                ;
03513                 BCS SKIP019             ;
03514
03515                 LDX MAXSPCOBJIND        ; Loop over all space objects in use
03516 LOOP021         LDA #255                ; Prep magic offscreen pixel number value
03517                 LDY ZPOSSIGN,X          ; Compare sign of z-coordinate with view mode
03518                 CPY SHIPVIEW            ;
03519                 BEQ SKIP018             ; Equal? Space object is offscreen -> New space obj!
03520
03521                 LDA YPOSSIGN,X          ; Prepare projection division...
03522                 BNE SKIP016             ; DIVIDEND (16-bit value) := ABS(y-coordinate)
03523                 SEC                     ; (used in subroutine PROJECTION)
03524                 LDA #0                  ;
03525                 SBC YPOSLO,X            ;
03526                 STA DIVIDEND            ;
03527                 LDA #0                  ;
03528                 SBC YPOSHI,X            ;
03529                 STA DIVIDEND+1          ;
03530                 JMP JUMP001             ;
03531 SKIP016         LDA YPOSLO,X            ;
03532                 STA DIVIDEND            ;
03533                 LDA YPOSHI,X            ;
03534                 STA DIVIDEND+1          ;
03535
03536 JUMP001         JSR PROJECTION          ; Calc pixel row number rel. to screen center
03537                 JSR SCREENROW           ; Calc pixel row number rel. to top-left of screen
03538
03539                 LDA XPOSSIGN,X          ; Prepare projection division...
03540                 BNE SKIP017             ; DIVIDEND (16-bit value) := ABS(x-coordinate)
03541                 SEC                     ; (used in subroutine PROJECTION)
03542                 LDA #0                  ;
03543                 SBC XPOSLO,X            ;
03544                 STA DIVIDEND            ;
03545                 LDA #0                  ;
03546                 SBC XPOSHI,X            ;
03547                 STA DIVIDEND+1          ;
03548                 JMP JUMP002             ;
03549 SKIP017         LDA XPOSLO,X            ;
03550                 STA DIVIDEND            ;
03551                 LDA XPOSHI,X            ;
03552                 STA DIVIDEND+1          ;
03553
03554 JUMP002         JSR PROJECTION          ; Calc pixel column number rel. to screen center
03555 SKIP018         JSR SCREENCOLUMN        ; Calc pixel column number rel. to top-left of screen
03556                 DEX                     ;
03557                 BPL LOOP021             ; Next space object
03558
03559 ;*** (13) Handle hyperwarp marker selection in Galactic Chart view *************
03560 SKIP019         JSR SELECTWARP          ; Handle hyperwarp marker in Galactic Chart view
03561
03562 ;*** (14) Compute and draw Long-Range Scan view star field on z-x plane ********
03563                 BIT SHIPVIEW            ; Skip if not in Long-Range Scan view
03564                 BVC SKIP022             ;
03565
03566                 LDX #$31                ; Draw our starship's shape
03567                 JSR DRAWLINES           ;
03568
03569                 BIT GCSTATLRS           ; Skip if Long-Range Scan destroyed
03570                 BVS SKIP022             ;
03571
03572                 LDX MAXSPCOBJIND        ; Loop over all space objects in use
03573 LOOP022         LDA ZPOSHI,X            ; Load z-coordinate (high byte)
03574                 LDY ZPOSSIGN,X          ; Load sign of z-coordinate
03575                 BNE SKIP020             ;
03576                 EOR #$FF                ; A := ABS(z-coordinate (high byte))
03577 SKIP020         TAY                     ;
03578                 LDA MAPTO80,Y           ; Calc pixel row number rel. to screen center
03579                 JSR SCREENROW           ; Calc pixel row number rel. to top-left of screen
03580
03581                 LDA XPOSHI,X            ; Load x-coordinate (high byte)
03582                 LDY XPOSSIGN,X          ; Load sign of x-coordinate
03583                 BNE SKIP021             ;
03584                 EOR #$FF                ; A := ABS(x-coordinate (high byte))
03585 SKIP021         TAY                     ;
03586                 LDA MAPTO80,Y           ; Calc pixel column number rel. to screen center
03587                 JSR SCREENCOLUMN        ; Calc pixel column number rel. to top-left of screen
03588
03589                 DEX                     ;
03590                 BPL LOOP022             ; Next space object
03591
03592 ;*** (15) Update PLAYER shapes, heights, and colors ****************************
03593
03594 ; DESCRIPTION
03595 ;
03596 ; In a loop over all PLAYERs, the following steps are executed:
03597 ;
03598 ; o   Clear the PLAYER shape offset and height.
03599 ;
03600 ; o   If in Galactic Chart view or in Long-Range Scan view, preload a random
03601 ;     color and a magic z-coordinate (distance value) for PLAYER3..4
03602 ;     (representing hyperwarp markers in Galactic Chart view and blips in the
03603 ;     Long-Range Scan view, like, for example, Zylon ships, meteors - or even
03604 ;     the Hyperwarp Target Marker during hyperwarp!).
03605 ;
03606 ; o   If in Front or Aft view, execute the following steps:
03607 ;
03608 ;      o   Skip dead PLAYERs.
03609 ;
03610 ;      o   Preload the distance value for the remaining live PLAYERs.
03611 ;
03612 ;      o   If we are in a starbase sector, combine PLAYER0..2 into a three-part
03613 ;          starbase shape. Compute the pixel column numbers and pixel row
03614 ;          numbers of PLAYER0..1 such that they are arranged left (PLAYER0) and
03615 ;          right (PLAYER1) of PLAYER2. In addition, preload a color mask, a
03616 ;          counter actually, that will make the starbase pulsate in brightness.
03617 ;
03618 ;     BUG (at $A512): The code at $A512 that skips the combination operation for
03619 ;     PLAYER2..4 jumps for PLAYER3..4 to SKIP025 at $A52A instead of SKIP026 at
03620 ;     $A52E. Thus it stores a color mask which does not only make the starbase
03621 ;     PLAYER0..2 pulsate in brightness but also PLAYER3..4 in a starbase sector,
03622 ;     for example the transfer vessel, photon torpedoes, etc. - or even the
03623 ;     Hyperwarp Target Marker when hyperwarping out of such a sector! Suggested
03624 ;     fix: None, code hard to untwist.
03625 ;
03626 ; o   After storing the color mask, check if the PLAYER shape is still above the
03627 ;     bottom edge of the PLAYFIELD.
03628 ;
03629 ;     BUG (at $A534): The test checks the vertical position of the top edge of
03630 ;     the PLAYER against the bottom edge of the PLAYFIELD above the Console
03631 ;     Panel Display (= Player/Missile pixel row number 204). This is not
03632 ;     completely accurate as the Console Panel Display starts at PM pixel row
03633 ;     number 208. For example, if you carefully navigate a starbase to the
03634 ;     bottom edge of the PLAYFIELD, at a certain point the center of the
03635 ;     starbase shape bleeds over the bottom edge of the PLAYFIELD (while
03636 ;     sometimes even losing its left and right wings!). Suggested fix: None, as
03637 ;     a more elaborate test may consume too many bytes of the cartridge ROM
03638 ;     memory in order to fix a rarely noticed visual glitch.
03639 ;
03640 ; o   Convert the preloaded distance value of a PLAYER space object closer than
03641 ;     $2000 (8192) <KM> into a range index of 0..15. PLAYER space objects more
03642 ;     distant than $2000 (8192) <KM> are skipped and not displayed.
03643 ;
03644 ;     Later, this range index will pick not only the correct brightness for the
03645 ;     PLAYER (the closer the space object the brighter its PLAYER) but also the
03646 ;     correct PLAYER shape cell and height (the closer the space object the
03647 ;     larger the PLAYER shape and height). 
03648 ;
03649 ; o   Update the PLAYER's shape offset and height. On the way to the shape
03650 ;     offset and height add the PLAYER's shape type to the range index and
03651 ;     divide it by 2 to arrive at the shape offset index and height index (the
03652 ;     same value). Use this index to pick the correct shape data and shape
03653 ;     heights from a set of shape cells and their corresponding heights, stored
03654 ;     in tables PLSHAPOFFTAB ($BE2F) and PLSHAPHEIGHTTAB ($BE7F), respectively.
03655 ;
03656 ;     Remember that magic distance value used in the Galactic Chart and
03657 ;     Long-Range Scan view? Its value of $F2 is actually part of a negative
03658 ;     z-coordinate which is inverted to $0D00, leading to a range index of 13,
03659 ;     which, after the division by 2, picks shape cell 6. Shape cell 6 (the
03660 ;     seventh shape cell) of all space objects (except the starbase) is the
03661 ;     Long-Range Scan blip's dot (see PLSHAPOFFTAB ($BE2F) and PLSHAPHEIGHTTAB
03662 ;     ($BE7F)).
03663 ;
03664 ; o   Update the PLAYER's color/brightness by picking the appropriate values
03665 ;     with the range index from lookup tables PLSHAPCOLORTAB ($BFD1) and
03666 ;     PLSHAPBRITTAB ($BFDB). Apply some special effects to the color/brightness
03667 ;     of certain PLAYERs, such as using random colors for Zylon basestars, or
03668 ;     using the precomputed pulsating brightness value for a starbase.
03669
03670 SKIP022         LDX #NUMSPCOBJ.PL       ; Loop over all PLAYER space objects (X index < 5)
03671 LOOP023         DEX                     ;
03672                 BPL SKIP023             ; Jump into loop body below
03673                 JMP JUMP003             ; Loop is finished, skip loop body
03674
03675 ;*** Clear PLAYER shape offsets and heights ************************************
03676 SKIP023         LDA #0                  ;
03677                 STA PL0SHAPOFF,X        ; Clear PLAYER shape offset
03678                 STA PL0HEIGHTNEW,X      ; Clear new PLAYER shape height
03679
03680 ;*** Preload stuff for hyperwarp markers and Long-Range Scan blips *************
03681                 BIT SHIPVIEW            ; Skip if not in Galactic Chart view
03682                 BPL SKIP024             ;
03683
03684                 CPX #3                  ; Next PLAYER space object if PLAYER0..2
03685                 BCC LOOP023             ;
03686
03687 LOOP024         LDA RANDOM              ; Prep random color mask for warp markers/LRS blips
03688                 LDY #$F2                ; Prep magic z-coordinate for warp markers/LRS blips
03689                 BMI SKIP026             ; Unconditional jump
03690
03691 SKIP024         CMP PL0LIFE,X           ; Next PLAYER space object if this PLAYER not alive
03692                 BEQ LOOP023             ;
03693
03694                 BVS LOOP024             ; Skip back if in Long-Range Scan view
03695
03696 ;*** Preload stuff for other views *********************************************
03697
03698                 LDY PL0ZPOSHI,X         ; Prep z-coordinate (high byte)
03699
03700 ;*** Combine PLAYER0..2 to starbase shape **************************************
03701                 BIT ISSTARBASESECT      ; Skip if no starbase in this sector
03702                 BVC SKIP026             ;
03703
03704                 CPX #2                  ; Skip if PLAYER2..4
03705                 BCS SKIP025             ; (!)
03706
03707                 LDA PL2COLUMN           ; Calc new PM pixel column number for PLAYER0..1:
03708                 CLC                     ; Load PLAYER2 (starbase center) pixel column number
03709                 ADC PLSTARBAOFFTAB,X    ; ...add PLAYER left/right offset (starbase wings)
03710                 STA PL0COLUMN,X         ; Store new PM pixel column number of starbase wing
03711
03712                 LDA PL2ROWNEW           ; Calc new PM pixel row number for PLAYER0..1:
03713                 CLC                     ; Add vertical offset (= 4 PM pixels) to PLAYER2's
03714                 ADC #4                  ;
03715                 STA PL0ROWNEW,X         ; Store new PM pixel row number of starbase wing
03716
03717                 LDY PL2ZPOSHI           ; Prep Y with z-coordinate (high byte) of starbase
03718
03719 SKIP025         LDA COUNT256            ; Prep color mask with B3..0 of counter
03720                 AND #$0F                ; ...(= brightness bits cause pulsating brightness)
03721
03722 SKIP026         STA L.COLORMASK         ; Store color mask
03723
03724 ;*** Check if PLAYER is below PLAYFIELD bottom edge ****************************
03725                 TYA                     ; A := z-coordinate (high byte)
03726
03727                 LDY PL0ROWNEW,X         ; Next PLAYER space object if top of PM shape...
03728                 CPY #204                ; ...is below PLAYFIELD bottom... (!)
03729                 BCS LOOP023             ; ...(PM pixel row number >= 204)
03730
03731 ;*** Convert PLAYER z-coordinate to range index in 0..15 ***********************
03732                 LDY SHIPVIEW            ; Skip if in Front view...
03733                 BEQ SKIP027             ;
03734                 EOR #$FF                ; ...else invert z-coordinate (high byte)
03735
03736 SKIP027         CMP #$20                ; Next PLAYER space object if this one too far away
03737                 BCS LOOP023             ; ...(z-coordinate >= $20** (8192) <KM>)
03738
03739                 CMP #16                 ; Load z-coordinate (high byte) and...
03740                 BCC SKIP028             ;
03741                 LDA #15                 ;
03742 SKIP028         STA L.RANGEINDEX        ; ...trim to range index in 0..15
03743
03744 ;*** Update PLAYER shape offset and height *************************************
03745                 ORA PL0SHAPTYPE,X       ; Calc offset to shape table (shape type+range index)
03746                 LSR A                   ;
03747                 TAY                     ; Divide by 2 to get offset in 0..7 into shape data
03748                 LDA PLSHAPOFFTAB,Y      ; Update new PLAYER shape offset
03749                 STA PL0SHAPOFF,X        ;
03750                 LDA PLSHAPHEIGHTTAB,Y   ; Update new PLAYER shape height
03751                 STA PL0HEIGHTNEW,X      ;
03752
03753 ;*** Calculate PLAYER color/brightness value ***********************************
03754                 TYA                     ; Pick color (B7..4) using PLAYER shape type
03755                 LSR A                   ;
03756                 LSR A                   ;
03757                 LSR A                   ;
03758                 TAY                     ;
03759                 LDA PLSHAPCOLORTAB,Y    ;
03760                 CPY #8                  ; Pick random color if ZYLON BASESTAR (shape type 8)
03761                 BNE SKIP029             ;
03762                 EOR RANDOM              ;
03763 SKIP029         LDY L.RANGEINDEX        ;
03764                 EOR PLSHAPBRITTAB,Y     ; Pick brightness (B3..0) using range index and merge
03765
03766                 EOR L.COLORMASK         ; Modify color/brightness of PLAYER
03767
03768                 LDY PLCOLOROFFTAB,X     ; Get PLAYER color offset
03769                 STA PL0COLOR,Y          ; Store color in PLAYER color register
03770                 JMP LOOP023             ; Next PLAYER space object
03771
03772 ;*** (16) Flash red alert ******************************************************
03773 JUMP003         LDY #$AF                ; Prep PLAYFIELD2 color {BRIGHT BLUE-GREEN}
03774                 LDX SHIELDSCOLOR        ; Prep Shields color {DARK GREEN} or {BLACK}
03775
03776                 LDA REDALERTLIFE        ; Skip if red alert is over
03777                 BEQ SKIP030             ;
03778
03779                 DEC REDALERTLIFE        ; Decrement lifetime of red alert
03780                 LDY #$4F                ; Prep PLAYFIELD2 color {BRIGHT ORANGE}
03781
03782                 AND #$20                ; Switch colors every 64 game loops
03783                 BEQ SKIP030             ;
03784
03785                 LDX #$42                ; Load BACKGROUND color {DARK ORANGE}
03786                 LDY #$60                ; Load PLAYFIELD2 color {DARK PURPLE BLUE}
03787
03788 SKIP030         STY PF2COLOR            ; Store PLAYFIELD2 color
03789                 STX BGRCOLOR            ; Store BACKGROUND color
03790
03791 ;*** (17) Update color of PLAYFIELD space objects (stars, explosion fragments) *
03792                 LDX MAXSPCOBJIND        ; Loop over all PLAYFIELD space objs (X index > 4)
03793 LOOP025         LDA ZPOSHI,X            ; Prep z-coordinate (high byte)
03794                 LDY SHIPVIEW            ;
03795                 CPY #1                  ; Skip if not in Aft view
03796                 BNE SKIP032             ;
03797
03798                 CMP #$F0                ; Skip if star not too far (z < $F0** (-4096) <KM>)
03799                 BCS SKIP031             ;
03800                 JSR INITPOSVEC          ; Re-init position vector
03801 SKIP031         EOR #$FF                ; Invert z-coordinate (high byte)
03802
03803 SKIP032         CMP #16                 ; Convert z-coordinate (high byte)
03804                 BCC SKIP033             ; ...into range index 0..15
03805                 LDA #15                 ;
03806
03807 SKIP033         ASL A                   ; Compute index to pixel color table:
03808                 AND #$1C                ; Use bits B3..1 from range index as B4..2.
03809                 ORA COUNT8              ; Combine with random bits B3..0 from counter
03810
03811                 TAY                     ;
03812                 LDA FOURCOLORPIXEL,Y    ; Load 1-byte bit pattern for 4 pixels of same color
03813                 STA L.FOURCOLORPIX      ; ...and temporarily save it
03814
03815                 LDA PIXELCOLUMN,X       ; Load pixel mask to mask 1 pixel out of 4 pixels:
03816                 AND #$03                ; Use B1..0 from pixel column number...
03817                 TAY                     ;
03818                 LDA PIXELMASKTAB,Y      ; ...to pick mask to filter pixel in byte
03819                 AND L.FOURCOLORPIX      ; ...AND with 1-byte bit pattern for 4 pixels
03820                 STA PIXELBYTE,X         ; ...store byte (used in repaint step of game loop)
03821
03822                 DEX                     ;
03823                 CPX #NUMSPCOBJ.PL       ;
03824                 BCS LOOP025             ; Next PLAYFIELD space object
03825
03826 ;*** (18) Skip input handling if in demo mode **********************************
03827                 BIT ISDEMOMODE          ; If in demo mode skip to function keys
03828                 BVC SKIP034             ;
03829                 JMP SKIP040             ;
03830
03831 ;*** (19) Handle keyboard input ************************************************
03832 SKIP034         JSR KEYBOARD            ; Handle keyboard input
03833
03834 ;*** (20) Handle joystick input ************************************************
03835                 LDA PORTA               ; Load Joystick 0 directions
03836                 TAY                     ; ...Bits B0..3 -> Right, left, down, up.
03837                 AND #$03                ; ...Bit = 0/1 -> Stick pressed/not pressed
03838                 TAX                     ; JOYSTICKY := +1 -> Up
03839                 LDA STICKINCTAB,X       ; JOYSTICKY :=  0 -> Centered
03840                 STA JOYSTICKY           ; JOYSTICKY := -1 -> Down
03841                 TYA                     ;
03842                 LSR A                   ;
03843                 LSR A                   ;
03844                 AND #$03                ;
03845                 TAX                     ; JOYSTICKX := -1 -> Left
03846                 LDA STICKINCTAB,X       ; JOYSTICKX :=  0 -> Centered
03847                 STA JOYSTICKX           ; JOYSTICKX := +1 -> Right
03848
03849 ;*** (21) Check if our starship's photon torpedoes have hit a target ***********
03850                 JSR COLLISION           ; Check if our starship's photon torpedoes have hit
03851
03852 ;*** (22) Handle joystick trigger **********************************************
03853                 JSR TRIGGER             ; Handle joystick trigger
03854
03855 ;*** (23) Handle Attack Computer and Tracking Computer *************************
03856                 BIT GCSTATCOM           ; Skip if Attack Computer destroyed
03857                 BVS SKIP038             ;
03858
03859                 LDA DRAINATTCOMP        ; Skip if Attack Computer off
03860                 BEQ SKIP038             ;
03861
03862                 LDA SHIPVIEW            ; Skip if not in Front view
03863                 BNE SKIP035             ;
03864
03865                 JSR UPDATTCOMP          ; Update Attack Computer Display
03866
03867 SKIP035         LDX TRACKDIGIT          ; Load index of tracked space object
03868
03869                 LDA ZYLONATTACKER       ; Skip if ship of current Zylon torpedo is tracked
03870                 BMI SKIP036             ;
03871                 TAX                     ; ...else override Tracking Computer...
03872                 ORA #$80                ;
03873                 STA ZYLONATTACKER       ; ...and mark Zylon torpedo's ship as being tracked
03874
03875 SKIP036         LDA PL0LIFE,X           ; Skip if tracked space object still alive
03876                 BNE SKIP037             ;
03877
03878                 TXA                     ;
03879                 EOR #$01                ;
03880                 TAX                     ;
03881                 LDA PL0LIFE,X           ; Check if other Zylon ship still alive
03882                 BNE SKIP037             ; ...yes -> Keep new index
03883                 LDX TRACKDIGIT          ; ...no  -> Revert to old index of tracked space obj
03884
03885 SKIP037         STX TRACKDIGIT          ; Store index of tracked space object
03886
03887                 LDA ISTRACKCOMPON       ; Skip if tracking computer is turned off
03888                 BEQ SKIP038             ;
03889
03890                 LDA SHIPVIEW            ; Skip if in Long-Range Scan or Galactic Chart view
03891                 CMP #2                  ;
03892                 BCS SKIP038             ;
03893
03894                 EOR #$01                ;
03895                 CMP ZPOSSIGN,X          ; Skip if tracked space object in our starship's...
03896                 BEQ SKIP038             ; ...view direction
03897
03898                 TAX                     ;
03899                 LDA TRACKKEYSTAB,X      ; Pick 'F' or 'A' (Front or Aft view) keyboard code
03900                 STA KEYCODE             ; ...and store it (= emulate pressing 'F' or 'A' key)
03901
03902 ;*** (24) Handle docking to starbase *******************************************
03903 SKIP038         JSR DOCKING             ; Handle docking to starbase
03904
03905 ;*** (25) Handle maneuvering ***************************************************
03906                 JSR MANEUVER            ; Handle maneuvering photon torpedoes and Zylon ships
03907
03908 ;*** (26) Was our starship hit by Zylon photon torpedo? ************************
03909                 LDA ISSTARBASESECT      ; Skip hit check if in starbase sector
03910                 BNE SKIP040             ;
03911
03912                 LDA PL2LIFE             ; Skip hit check if PLAYER2 (Zylon photon torpedo)...
03913                 BEQ SKIP040             ; ...not alive
03914
03915                 LDY PL2ZPOSHI           ; Our starship was not hit if Zylon photon torpedo's
03916                 INY                     ; ...z-coordinate is not in -256..255 <KM> or...
03917                 CPY #$02                ;
03918                 BCS SKIP040             ;
03919
03920                 LDY PL2XPOSHI           ; ...x-coordinate is not in -256..255 <KM> or...
03921                 INY                     ;
03922                 CPY #$02                ;
03923                 BCS SKIP040             ;
03924
03925                 LDY PL2YPOSHI           ; ...y-coordinate is not in -256..255 <KM>.
03926                 INY                     ;
03927                 CPY #$02                ;
03928                 BCS SKIP040             ;
03929
03930 ;*** (27) Our starship was hit! ************************************************
03931                 JSR DAMAGE              ; Damage or destroy some subsystem
03932
03933                 LDY #2                  ; Trigger explosion at PLAYER2 (Zylon photon torpedo)
03934                 JSR INITEXPL            ;
03935
03936                 LDX #$7F                ; Prep HITBADNESS := SHIELDS HIT
03937                 LDA SHIELDSCOLOR        ; Skip if Shields are up (SHIELDSCOLOR not {BLACK}).
03938                 BNE SKIP039             ;
03939
03940                 LDX #$0A                ; Set Front view
03941                 JSR SETVIEW             ;
03942
03943                 LDY #$23                ; Set title phrase "SHIP DESTROYED BY ZYLON FIRE"
03944                 LDX #8                  ; Set mission bonus offset
03945                 JSR GAMEOVER            ; Game over
03946
03947                 LDX #$5F                ; Hide Control Panel Display (bottom text window)
03948                 LDY #$80                ;
03949                 LDA #$08                ;
03950                 JSR MODDLST             ;
03951
03952                 JSR CLRPLAYFIELD        ; Clear PLAYFIELD
03953
03954                 LDX #64                 ; Enable STARSHIP EXPLOSION noise (see SOUND)
03955                 STX NOISEHITLIFE        ;
03956
03957                 LDX #$FF                ; Prep HITBADNESS := STARSHIP DESTROYED
03958
03959 SKIP039         STX HITBADNESS          ; Store HITBADNESS
03960                 LDA #0                  ; Zylon photon torpedo lifetime := 0 game loops
03961                 STA PL2LIFE             ;
03962                 LDA #2                  ; Init Zylon photon torpedo trigger
03963                 STA TORPEDODELAY        ;
03964
03965                 LDX #1                  ; ENERGY := ENERGY - 100 after photon torpedo hit
03966                 JSR DECENERGY           ;
03967
03968                 LDX #$0A                ; Play noise sound pattern SHIELD EXPLOSION
03969                 JSR NOISE               ;
03970
03971 ;*** (28) Handle function keys *************************************************
03972 SKIP040         LDY FKEYCODE            ; Prep old function key code
03973                 LDA CONSOL              ; POKEY: Load function key code
03974
03975                 EOR #$FF                ; Store inverted and masked function key code
03976                 AND #$03                ;
03977                 STA FKEYCODE            ;
03978                 BEQ SKIP042             ; Skip if no function key pressed
03979
03980                 DEY                     ;
03981                 BPL SKIP042             ; Skip if SELECT or START still pressed
03982                 STA IDLECNTHI           ; Reset idle counter to a value in 1..3 (?)
03983                 CMP #2                  ; Skip if SELECT function key pressed
03984                 BCS SKIP041             ;
03985
03986                 LDA #0                  ; START function key pressed:
03987                 TAY                     ; Prep empty title phrase offset
03988                 JMP INITSTART           ; Reenter game loop via INITSTART
03989
03990 SKIP041         INC MISSIONLEVEL        ; SELECT function key pressed:
03991                 LDA MISSIONLEVEL        ; Cycle through next of 4 mission levels
03992                 AND #$03                ;
03993                 STA MISSIONLEVEL        ;
03994                 JMP INITSELECT          ; Reenter game loop via INITSELECT
03995
03996 ;*** (29) Update Control Panel Display *****************************************
03997 SKIP042         JSR UPDPANEL            ; Update Control Panel Display
03998
03999 ;*** (30) Handle hyperwarp *****************************************************
04000                 JSR HYPERWARP           ; Handle hyperwarp
04001
04002 ;*** (31) Update title line ****************************************************
04003                 JSR UPDTITLE            ; Update title line
04004
04005 ;*** (32) Flush game loop iteration ********************************************
04006                 JSR FLUSHGAMELOOP       ; Move Zylon units, age torpedoes, elapse time
04007
04008 ;*** (33) Jump back to begin of game loop **************************************
04009                 JMP GAMELOOP            ; Next game loop iteration
04010
04011 ;*******************************************************************************
04012 ;*                                                                             *
04013 ;*                                  VBIHNDLR                                   *
04014 ;*                                                                             *
04015 ;*                      Vertical Blank Interrupt Handler                       *
04016 ;*                                                                             *
04017 ;*******************************************************************************
04018
04019 ; DESCRIPTION
04020 ;
04021 ; This subroutine is executed during the Vertical Blank Interrupt (VBI) when the
04022 ; TV beam has reached the bottom-right corner of the TV screen and is switched
04023 ; off to return to the top-left position. This situation is called the "vertical
04024 ; blank phase".
04025 ;
04026 ; This subroutine signals its execution with flag ISVBISYNC ($67) (which is
04027 ; examined by GAMELOOP ($A1F3) to synchronize the execution of the game loop
04028 ; with the start of this subroutine). Then it switches the character set to the
04029 ; ROM character set, sets the BACKGROUND color depending on the severity of a
04030 ; Zylon photon torpedo hit and view mode, copies PLAYER and PLAYFIELD color
04031 ; registers to their corresponding hardware registers, clears the Player/Missile
04032 ; collision registers, calls the sound effects code in subroutine SOUND ($B2AB),
04033 ; and increments the idle counter. If the idle counter reaches the value $8000
04034 ; the title phrase is cleared and the game is switched to demo mode.
04035 ;
04036 ; BUG (at $A6EC): Because the values of SHIPVIEW ($D0) are $00, $01, $40, and
04037 ; $80, a value of 3 overspecifies the comparison. Suggested fix: Replace CMP #3
04038 ; with CMP #2, which may make the code clearer.
04039 ;
04040 ; BUG (at $A712): Demo mode is entered via a JMP instruction, which proceeds
04041 ; directly into GAMELOOP ($A1F3). Thus code execution never returns to pop the
04042 ; registers pushed on the stack during entry of this subroutine. Suggested fix:
04043 ; None.
04044
04045 VBIHNDLR        LDA #$FF                ; Signals entering Vertical Blank Interrupt
04046                 STA ISVBISYNC           ;
04047
04048                 LDA #>ROMCHARSET        ; Switch character set to ROM character set
04049                 STA CHBASE              ;
04050
04051                 LDX BGRCOLOR            ; Preload BACKGROUND color
04052                 LDA RANDOM              ; Preload random number
04053                 BIT HITBADNESS          ; Check if our starship was hit
04054                 BVC SKIP044             ; If HITBADNESS has a value of...
04055                 BMI SKIP043             ; $00 -> NO HIT             (BGR color := unchanged)
04056                 AND #$72                ; $7F -> SHIELDS HIT        (BGR color := %01rr00r0)
04057                 ORA #$40                ; $FF -> STARSHIP DESTROYED (BGR color := %01rr00r0)
04058 SKIP043         TAX                     ;
04059 SKIP044         LDA SHIPVIEW            ; Skip if in Front or Aft view
04060                 CMP #3                  ; (!)
04061                 BCC SKIP045             ;
04062                 LDX #$A0                ; Preload BACKGROUND color {DARK BLUE GREEN}...
04063 SKIP045         STX BGRCOLOR            ; Store BACKGROUND color
04064
04065                 LDX #8                  ; Copy all color registers to hardware registers
04066 LOOP026         LDA PL0COLOR,X          ;
04067                 STA COLPM0,X            ;
04068                 DEX                     ;
04069                 BPL LOOP026             ;
04070
04071                 STA HITCLR              ; Clear Player/Missile collision registers
04072
04073                 JSR SOUND               ; Call sound effects
04074
04075                 INC IDLECNTLO           ; Increment 16-bit idle counter
04076                 BNE SKIP046             ;
04077                 LDA IDLECNTHI           ;
04078                 BMI SKIP046             ;
04079                 INC IDLECNTHI           ;
04080                 BPL SKIP046             ; Skip if idle counter value of $8000 not reached yet
04081
04082                 LDY #$00                ; Prep empty title phrase offset
04083                 JMP INITDEMO            ; Enter demo mode (!)
04084
04085 SKIP046         JMP JUMP004             ; Return via DLI return code
04086
04087 ;*******************************************************************************
04088 ;*                                                                             *
04089 ;*                                  DLSTHNDLR                                  *
04090 ;*                                                                             *
04091 ;*                       Display List Interrupt Handler                        *
04092 ;*                                                                             *
04093 ;*******************************************************************************
04094
04095 ; DESCRIPTION
04096 ;
04097 ; This subroutine is executed during the Display List Interrupt (DLI). It
04098 ; switches the character set to the ROM character set if the DLI occurs at ANTIC
04099 ; line 96 (video line 192), otherwise to the custom character set. The former
04100 ; happens in the Galactic Chart view where the ROM character set is used in the
04101 ; Galactic Chart Panel Display.
04102 ;
04103 ; Then, the DLI PLAYFIELD colors are copied to the corresponding hardware
04104 ; registers and the values of the collision hardware registers for PLAYER3..4
04105 ; (our starship's photon torpedoes) are copied to the corresponding zero page
04106 ; variables PL3HIT ($82) and PL4HIT ($83).
04107
04108 DLSTHNDLR       PHA                     ; Push A
04109                 TXA                     ;
04110                 PHA                     ; Push X
04111                 TYA                     ;
04112                 PHA                     ; Push Y
04113
04114                 LDA #>ROMCHARSET        ; Switch to ROM charset if ANTIC line counter = 96
04115                 LDY VCOUNT              ; ...else switch to custom character set
04116                 CPY #96                 ;
04117                 BEQ SKIP047             ;
04118                 LDA #>CHARSET           ;
04119 SKIP047         STA CHBASE              ;
04120
04121                 LDX #4                  ; Loop over all PLAYFIELD colors
04122                 STA WSYNC               ; Stop and wait for horizontal TV beam sync
04123 LOOP027         LDA PF0COLORDLI,X       ; Copy DLI PLAYFIELD colors to hardware registers
04124                 STA COLPF0,X            ;
04125                 DEX                     ;
04126                 BPL LOOP027             ; Next PLAYFIELD color
04127
04128                 LDA M0PL                ; Merge MISSILE-to-PLAYER collision registers...
04129                 ORA M1PL                ;
04130                 ORA M2PL                ;
04131                 ORA M3PL                ;
04132                 STA PL4HIT              ; ...and store them in PL4HIT
04133                 LDA P3PL                ; Copy PLAYER3-to-PLAYER coll. register to PL3HIT
04134                 STA PL3HIT              ;
04135
04136 JUMP004         PLA                     ; Pop Y
04137                 TAY                     ;
04138                 PLA                     ; Pop X
04139                 TAX                     ;
04140                 PLA                     ; Pop A
04141                 RTI                     ; Return from interrupt
04142
04143 ;*******************************************************************************
04144 ;*                                                                             *
04145 ;*                                  IRQHNDLR                                   *
04146 ;*                                                                             *
04147 ;*                       Interrupt Request (IRQ) Handler                       *
04148 ;*                                                                             *
04149 ;*******************************************************************************
04150
04151 ; DESCRIPTION
04152 ;
04153 ; This subroutine is executed during immediate interrupt requests (IRQs), such
04154 ; as after pressing a key on the keyboard. It clears and disables all IRQs
04155 ; except the interrupt raised by a pressed key. If a key has been pressed, its
04156 ; hardware code is collected and the bits of the SHIFT and CONTROL keys are
04157 ; added. The resulting keyboard code is stored in KEYCODE ($CA).
04158
04159 IRQHNDLR        PHA                     ; Push A
04160                 LDA #0                  ; POKEY: Disable all IRQs
04161                 STA IRQEN               ;
04162                 LDA #$40                ; POKEY: Enable keyboard interrupt (IRQ)
04163                 STA IRQEN               ;
04164                 LDA KBCODE              ; POKEY: Load keyboard key code
04165                 ORA #$C0                ; Combine with SHIFT and CONTROL key bits
04166                 STA KEYCODE             ; Store keyboard code
04167                 PLA                     ; Pop A
04168                 RTI                     ; Return from interrupt
04169
04170 ;*******************************************************************************
04171 ;*                                                                             *
04172 ;*                                  DRAWLINES                                  *
04173 ;*                                                                             *
04174 ;*                     Draw horizontal and vertical lines                      *
04175 ;*                                                                             *
04176 ;*******************************************************************************
04177
04178 ; DESCRIPTION
04179 ;
04180 ; Draws the Attack Computer Display (in Front view), cross hairs (in Front and
04181 ; Aft view), and our starship's shape (in Long-Range Scan view) on the PLAYFIELD
04182 ; (if the Attack Computer is not destroyed) by being passed an offset to table
04183 ; DRAWLINESTAB ($BAF9). This table consists of a list of 3-byte elements,
04184 ; terminated by an end marker byte ($FE). Each such element defines a single
04185 ; horizontal or vertical line, and is passed via memory addresses DIRLEN ($A4),
04186 ; PENROW ($A5), and PENCOLUMN ($A6) to subroutine DRAWLINE ($A782), which
04187 ; executes the actual drawing. See subroutine DRAWLINE ($A782) and table
04188 ; DRAWLINESTAB ($BAF9) for a description of the 3-byte elements. 
04189 ;
04190 ; With every call of this subroutine the blip cycle counter is initialized to
04191 ; the start of the DELAY phase (see subroutine UPDATTCOMP ($A7BF)).
04192 ;
04193 ; NOTE: The entry to this subroutine is in mid-code, not at the beginning.
04194 ;
04195 ; INPUT
04196 ;
04197 ;   X = Offset into DRAWLINESTAB ($BAF9). Used values are:
04198 ;     $00 -> Draw Attack Computer Display and cross hairs (Front view)
04199 ;     $2A -> Draw Aft view cross hairs (Aft view)
04200 ;     $31 -> Draw our starship's shape (Long-Range Scan view)
04201
04202 LOOP028         STA DIRLEN,Y            ; Store byte of 3-byte element
04203                 INX                     ;
04204                 DEY                     ;
04205                 BPL SKIP048             ; Next byte of 3-byte element until 3 bytes copied
04206                 JSR DRAWLINE            ; Draw line on PLAYFIELD
04207
04208 DRAWLINES       LDA #5                  ; Init blip cycle to DELAY phase...
04209                 STA BLIPCYCLECNT        ; ...delays drawing each row
04210
04211                 BIT GCSTATCOM           ; Return if Attack Computer destroyed
04212                 BVS SKIP049             ;
04213
04214                 LDY #2                  ;
04215 SKIP048         LDA DRAWLINESTAB,X      ; Load byte of 3-byte element
04216                 CMP #$FE                ; Loop until end marker byte ($FE) encountered
04217                 BNE LOOP028             ;
04218 SKIP049         RTS                     ; Return
04219
04220 ;*******************************************************************************
04221 ;*                                                                             *
04222 ;*                                  DRAWLINE                                   *
04223 ;*                                                                             *
04224 ;*                  Draw a single horizontal or vertical line                  *
04225 ;*                                                                             *
04226 ;*******************************************************************************
04227
04228 ; DESCRIPTION
04229 ;
04230 ; Draws a single horizontal or vertical transparent line.
04231 ;
04232 ; There are two entries to this subroutine:
04233 ;
04234 ; (1)  DRAWLINE ($A782) is entered from subroutine DRAWLINES ($A76F) to draw a
04235 ;      line in COLOR1.
04236 ;
04237 ; (2)  DRAWLINE2 ($A784) is entered from subroutine UPDATTCOMP ($A7BF) to draw
04238 ;      the blip in COLOR2 in the Attack Computer Display.
04239 ;
04240 ; The position, direction, and length of the line is defined by three bytes
04241 ; passed in memory addresses DIRLEN ($A4), PENROW ($A5), and PENCOLUMN ($A6). 
04242 ;
04243 ; A drawing operation draws one transparent line. It uses both the color
04244 ; register number of the overwritten (old) and the overwriting (new) pixel to
04245 ; decide on the new pixel color register number. This results in a transparent
04246 ; drawing effect. See the table below for all resulting combinations of color
04247 ; registers.
04248 ;
04249 ; +-----------+---------------+
04250 ; |           |   Old Color   |
04251 ; |           |   Register    |
04252 ; | New Color +---------------+
04253 ; | Register  | 0 | 1 | 2 | 3 |
04254 ; +-----------+---+---+---+---+
04255 ; |         0 | 0 | 1 | 2 | 3 |
04256 ; +-----------+---+---+---+---+
04257 ; |         1 | 1 | 1 | 3 | 3 |
04258 ; +-----------+---+---+---+---+
04259 ; |         2 | 2 | 3 | 2 | 3 |
04260 ; +-----------+---+---+---+---+
04261 ; |         3 | 3 | 3 | 3 | 3 |
04262 ; +-----------+---+---+---+---+
04263 ;
04264 ; For example, COLOR1 overwritten by COLOR2 yields COLOR3. If you look closely
04265 ; at the blip (in COLOR2) on the Attack Computer Display (in COLOR1) the lines
04266 ; of the Attack Computer Display shine through (in COLOR3) where they overlap.
04267 ;
04268 ; INPUT
04269 ;
04270 ;   DIRLEN    ($A4) = B7 = 0 -> Draw line to the right
04271 ;                     B7 = 1 -> Draw line downward
04272 ;                     B6..0  -> Length of line in pixels
04273 ;   PENROW    ($A5) = Start pixel row number of line
04274 ;   PENCOLUMN ($A6) = Start pixel column number of line
04275
04276 L.PIXELBYTEOFF  = $6A                   ; Within-row-offset to byte with pixel in PLAYFIELD
04277 L.BITPAT        = $6B                   ; 1-byte bit pattern for 4 pixels of same color
04278 L.DIRSAV        = $6E                   ; Saves DIRLEN
04279
04280 DRAWLINE        LDA #$55                ; Copy 1-byte bit pattern for 4 pixels of COLOR1
04281 DRAWLINE2       STA L.BITPAT            ;
04282                 LDA DIRLEN              ; Copy direction (and length) of line
04283                 STA L.DIRSAV            ;
04284                 AND #$7F                ; Strip direction bit
04285                 STA DIRLEN              ; Store length of line
04286
04287 LOOP029         LDY PENROW              ; Loop over length of line to be drawn
04288                 LDA PFMEMROWLO,Y        ; Point MEMPTR to start of pen's pixel row...
04289                 STA MEMPTR              ; ...in PLAYFIELD memory
04290                 LDA PFMEMROWHI,Y        ;
04291                 STA MEMPTR+1            ;
04292
04293                 LDA PENCOLUMN           ; Calc and store pen's byte-within-row offset
04294                 LSR A                   ;
04295                 LSR A                   ;
04296                 STA L.PIXELBYTEOFF      ;
04297
04298                 LDA PENCOLUMN           ; Calc pixel-within-byte index
04299                 AND #$03                ;
04300                 TAY                     ;
04301
04302                 LDA PIXELMASKTAB,Y      ; Pick mask to filter pixel in byte
04303                 AND L.BITPAT            ; ...AND with bit pattern for 4 pixels of same color
04304                 LDY L.PIXELBYTEOFF      ;
04305                 ORA (MEMPTR),Y          ; Blend byte with new pixel and PLAYFIELD byte
04306                 STA (MEMPTR),Y          ; ...and store it back in PLAYFIELD memory
04307
04308                 BIT L.DIRSAV            ; Check direction bit B7
04309                 BPL SKIP050             ;
04310                 INC PENROW              ; If B7 = 1 -> Increment pen's pixel row number
04311                 BNE SKIP051             ;
04312 SKIP050         INC PENCOLUMN           ; If B7 = 0 -> Increment pen's pixel column number
04313
04314 SKIP051         DEC DIRLEN              ;
04315                 BNE LOOP029             ; Next pixel of line
04316                 RTS                     ; Return
04317
04318 ;*******************************************************************************
04319 ;*                                                                             *
04320 ;*                                 UPDATTCOMP                                  *
04321 ;*                                                                             *
04322 ;*                       Update Attack Computer Display                        *
04323 ;*                                                                             *
04324 ;*******************************************************************************
04325
04326 ; DESCRIPTION
04327 ;
04328 ; Draws the blip of the tracked space object and the lock-on markers into the
04329 ; Attack Computer Display. The actual drawing follows a cycle of 11 game loop
04330 ; iterations (numbered by this subroutine as "blip cycles" 0..10), which can be
04331 ; divided into three phases:
04332 ;
04333 ; (1)  Blip cycle 0..4: Draw blip shape row-by-row
04334 ;
04335 ;      Draw the blip's shape into the Attack Computer Display, one row each blip
04336 ;      cycle. After 5 blip cycles the blip shape is complete and completely
04337 ;      visible because between blip cycles, that is, game loop iterations, the
04338 ;      PLAYFIELD is not erased (only the PLAYFIELD space objects are). Drawing
04339 ;      is executed by branching to entry DRAWLINE2 ($A784) of subroutine
04340 ;      DRAWLINE ($A782). The blip shape is retrieved from table BLIPSHAPTAB
04341 ;      ($BF6E).
04342 ;
04343 ; (2)  Blip cycle 5..9: Delay
04344 ;
04345 ;      Delay the execution of blip cycle 10.
04346 ;
04347 ; (3)  Blip cycle 10: Update Attack Computer Display
04348 ;
04349 ;      After verifying that the tracked space object is alive, calculate the
04350 ;      blip's relative top-left pixel column and row number. The resulting
04351 ;      values are in -11..11 and -6..4, relative to the blip's top-left
04352 ;      reference position at pixel column number 131 and pixel row number 77,
04353 ;      respectively. 
04354 ;
04355 ;      Filter the Attack Computer Display area: Only pixels of COLOR1 within the
04356 ;      inner frame area (a 28 pixel wide x 15 pixel high rectangle with its
04357 ;      top-left corner at pixel column number 120 and pixel row number 71) pass
04358 ;      the filter operation. This effectively erases the blip.
04359 ;
04360 ;      If the blip is within -2..+2 pixels off its horizontal reference position
04361 ;      (pixel column numbers 129..132) then the tracked space object is in x
04362 ;      lock-on. Draw the x lock-on marker. 
04363 ;
04364 ;      If the tracked space object is in x lock-on and the blip is within -2..+1
04365 ;      pixels off its vertical reference position (pixel column numbers 75..78)
04366 ;      then the tracked space object is in x and y lock-on. Draw also the y
04367 ;      lock-on marker. 
04368 ;
04369 ;      If the tracked space object is in x and y lock-on and the tracked space
04370 ;      object's z-coordinate < +3072 (+$0C**) <KM> then the tracked space object
04371 ;      is in x, y and z lock-on. Draw also the z lock-on marker. 
04372 ;
04373 ;      If the tracked space object is in x, y, and z lock-on (and thus in
04374 ;      optimal firing range) set the ISINLOCKON ($A3) flag.
04375 ;
04376 ;      The following sketches show the Attack Computer Display area overlaid
04377 ;      with the Attack Computer Display frame:
04378 ;
04379 ;          119                                 119
04380 ;      70 ##############################    70 ##############################
04381 ;         #         ....#....          #       #             #              #
04382 ;         #         ....#....          #       #             #              #
04383 ;         #         ....#....          #       #             #              #
04384 ;         #         ....#....          #       #             #              #
04385 ;         #      ###############       #       #......###############.......#
04386 ;         #XXXX  #  .........  #   XXXX#       #......#.............#.......#
04387 ;         #      #  ..$......  #       #       #......#....$........#.......#
04388 ;         ########  .........  #########       ########.............#########
04389 ;         #      #  .........  #       #       #......#.............#.......#
04390 ;         #      #  .........  #       #       #YYYY..#.............#...YYYY#
04391 ;         #      ###############       #       #......###############.......#
04392 ;         #         ....#....          #       #.............#..............#
04393 ;         #         ....#....          #       #             #              #
04394 ;         #         ....#....          #       #             #              #
04395 ;         #         ....#....          #       #             #              #
04396 ;         ##############################       ##############################
04397 ;
04398 ;         X = x lock-on marker                 Y = y lock-on marker
04399 ;         . = x lock-on blip zone              . = y lock-on blip zone
04400 ;         $ = Blip's top-left reference        $ = Blip's top-left reference
04401 ;             position                             position
04402 ;
04403 ;         119
04404 ;      70 ##############################
04405 ;         #             #              #
04406 ;         #             #              #
04407 ;         #             #              #
04408 ;         #             #              #
04409 ;         #      ###############       #
04410 ;         #      #             #       #
04411 ;         #      #    $        #       #
04412 ;         ########             #########
04413 ;         #      #             #       #
04414 ;         #      #             #       #
04415 ;         #      ###############       #
04416 ;         #             #              #
04417 ;         #             #              #
04418 ;         #        ZZ   #  ZZ          #
04419 ;         #        ZZ   #  ZZ          #
04420 ;         ##############################
04421 ;
04422 ;         Z = z lock-on marker
04423 ;         $ = Blip's top-left reference
04424 ;             position
04425
04426 L.SHIFTSHAP     = $6C                   ; Saves shifted byte of blip shape bit pattern
04427
04428 UPDATTCOMP      LDX TRACKDIGIT          ; Load index of tracked space object
04429                 LDY BLIPCYCLECNT        ; Load blip cycle counter
04430                 CPY #5                  ;
04431                 BCS SKIP054             ; Skip drawing blip if blip cycle > 5
04432
04433 ;*** Blip cycle 0..4: Draw blip shape one row each cycle ***********************
04434                 LDA BLIPCOLUMN          ; Init pen's pixel column number...
04435                 STA PENCOLUMN           ; ...with top position of blip shape
04436                 LDA BLIPSHAPTAB,Y       ; Load bit pattern of one row of blip shape
04437 LOOP030         ASL A                   ; Shift bit pattern one position to the left
04438                 STA L.SHIFTSHAP         ; Temporarily save shifted shape byte
04439                 BCC SKIP052             ; Skip if shifted-out bit = 0
04440
04441                 LDA #$81                ; Store "draw a line of 1 pixel length downward"
04442                 STA DIRLEN              ; ...for call to DRAWLINE2
04443
04444                 LDA BLIPROW             ; Init pen's pixel row number...
04445                 STA PENROW              ; ...with leftmost position of blip shape
04446                 LDA #$AA                ; Load 1-byte bit pattern for 4 pixels of COLOR2
04447                 JSR DRAWLINE2           ; Draw pixel on PLAYFIELD
04448
04449 SKIP052         INC PENCOLUMN           ; Move pen one pixel to the right
04450                 LDA L.SHIFTSHAP         ; Reload shifted shape byte
04451                 BNE LOOP030             ; Next horizontal pixel of blip shape
04452
04453                 INC BLIPROW             ; Move pen one pixel downward
04454 SKIP053         INC BLIPCYCLECNT        ; Increment blip cycle counter
04455                 RTS                     ; Return
04456
04457 ;*** Blip cycle 5..9: Delay ****************************************************
04458 SKIP054         CPY #10                 ; Return if blip cycle < 10
04459                 BCC SKIP053             ;
04460
04461 ;*** Blip cycle 10: Calculate new blip pixel row and column numbers ************
04462                 LDA PL0LIFE,X           ; Skip if tracked object not alive
04463                 BEQ SKIP059             ;
04464
04465                 LDA XPOSHI,X            ; Map x-coordinate of tracked space obj to -11..11:
04466                 LDY XPOSSIGN,X          ; Skip if tracked object on left screen half (x >= 0)
04467                 BEQ SKIP055             ;
04468
04469                 CMP #12                 ; Skip if x of tracked obj < +$0C** (< 3327) <KM>
04470                 BCC SKIP056             ;
04471                 LDA #11                 ; Prep relative pixel column number of 11, skip
04472                 BPL SKIP056             ;
04473
04474 SKIP055         CMP #-11                ; Skip if x of tracked obj >= -($0B**) (>=-2816) <KM>
04475                 BCS SKIP056             ;
04476                 LDA #-11                ; Prep relative pixel column number of -11
04477
04478 SKIP056         CLC                     ; Add 131 (= blip's top-left reference pixel column)
04479                 ADC #131                ;
04480                 STA BLIPCOLUMN          ; BLIPCOLUMN := 131 + -11..11
04481
04482                 LDA YPOSHI,X            ; Map y-coordinate of tracked space obj to -6..4:
04483                 EOR #$FF                ; Mirror y-coordinate on y-axis (displacement of +1)
04484                 LDY YPOSSIGN,X          ; Skip if tracked obj on lower screen half (y < 0)
04485                 BNE SKIP057             ;
04486
04487                 CMP #5                  ; Skip if mirrored y of tracked obj < +$05** <KM>
04488                 BCC SKIP058             ;
04489                 LDA #4                  ; Prep relative pixel row number of 4, skip
04490                 BPL SKIP058             ;
04491
04492 SKIP057         CMP #-6                 ; Skip if mirrored y of tracked obj >= -($06**) <KM>
04493                 BCS SKIP058             ;
04494                 LDA #-6                 ; Prep relative pixel row number of -6
04495
04496 SKIP058         CLC                     ; Add 77 (= blip's top-left ref. pixel row number)
04497                 ADC #77                 ;
04498                 STA BLIPROW             ; BLIPROW := 77 + -6..4
04499
04500                 LDA #0                  ; Reset blip cycle
04501                 STA BLIPCYCLECNT        ;
04502
04503 ;*** Filter Attack Computer Display frame area *********************************
04504                                         ; PLAYFIELD address of top-left of Attack Computer
04505 PFMEM.C120R71   = PFMEM+71*40+120/4     ; Display's inner frame @ pixel column 120, row 71
04506
04507 SKIP059         LDA #<PFMEM.C120R71     ; Point MEMPTR to start of frame's...
04508                 STA MEMPTR              ; ...inner top-left corner at column 120, row 71...
04509                 LDA #>PFMEM.C120R71     ; ...in PLAYFIELD memory
04510                 STA MEMPTR+1            ;
04511
04512                 LDX #14                 ; Traverse a 28 x 15 pixel rect of PLAYFIELD memory
04513 LOOP031         LDY #6                  ;
04514 LOOP032         LDA (MEMPTR),Y          ; Load byte (4 pixels) from PLAYFIELD memory
04515                 AND #$55                ; Filter COLOR1 pixels
04516                 STA (MEMPTR),Y          ; Store byte (4 pixels) back to PLAYFIELD memory
04517                 DEY                     ;
04518                 BPL LOOP032             ; Next 4 pixels in x-direction
04519
04520                 CLC                     ; Add 40 to MEMPTR
04521                 LDA MEMPTR              ; (40 bytes = 160 pixels = 1 PLAYFIELD row of pixels)
04522                 ADC #40                 ;
04523                 STA MEMPTR              ;
04524                 BCC SKIP060             ;
04525                 INC MEMPTR+1            ;
04526
04527 SKIP060         DEX                     ;
04528                 BPL LOOP031             ; Next row of pixels in y-direction
04529
04530 ;*** Prepare lock-on marker checks *********************************************
04531                 LDX TRACKDIGIT          ; Preload index of tracked space obj to check z-range
04532                 INY                     ; Y := 0, preloaded value of ISINLOCKON
04533
04534 ;*** Draw lock-on markers ******************************************************
04535                                         ; PLAYFIELD addresses of
04536 PFMEM.C120R76   = PFMEM+76*40+120/4     ; ...x lock-on marker @ pixel column 120, row 76
04537 PFMEM.C144R76   = PFMEM+76*40+144/4     ; ...x lock-on marker @ pixel column 144, row 76
04538 PFMEM.C120R80   = PFMEM+80*40+120/4     ; ...y lock-on marker @ pixel column 120, row 80
04539 PFMEM.C144R80   = PFMEM+80*40+144/4     ; ...y lock-on marker @ pixel column 144, row 80
04540 PFMEM.C128R84   = PFMEM+84*40+128/4     ; ...z lock-on marker @ pixel column 128, row 84
04541 PFMEM.C128R85   = PFMEM+85*40+128/4     ; ...z lock-on marker @ pixel column 128, row 85
04542 PFMEM.C136R84   = PFMEM+84*40+136/4     ; ...z lock-on marker @ pixel column 136, row 84
04543 PFMEM.C136R85   = PFMEM+85*40+136/4     ; ...z lock-on marker @ pixel column 136, row 85
04544
04545                 LDA LOCKONLIFE          ; If lock-on lifetime expired redraw lock-on markers
04546                 BEQ SKIP061             ;
04547
04548                 DEC LOCKONLIFE          ; else decrem. lock-on lifetime, skip drawing markers
04549                 BNE SKIP062             ;
04550
04551 SKIP061         LDA BLIPCOLUMN          ; Skip x, y, and z lock-on marker if blip's...
04552                 CMP #129                ; ...top-left pixel column number not in 129..132
04553                 BCC SKIP062             ;
04554                 CMP #133                ;
04555                 BCS SKIP062             ;
04556
04557                 LDA #$AA                ; Draw x lock-on marker (4 horiz. pixels of COLOR2)
04558                 STA PFMEM.C120R76       ; ...at pixel column 120, row 76
04559                 STA PFMEM.C144R76       ; ...at pixel column 144, row 76
04560
04561                 LDA BLIPROW             ; Skip y and z lock-on marker if blip's...
04562                 CMP #75                 ; ...top-left pixel row number not in 75...78
04563                 BCC SKIP062             ;
04564                 CMP #79                 ;
04565                 BCS SKIP062             ;
04566
04567                 LDA #$AA                ; Draw y lock-on marker (4 horiz. pixels of COLOR2)
04568                 STA PFMEM.C120R80       ; ...at pixel column 120, row 80
04569                 STA PFMEM.C144R80       ; ...at pixel column 144, row 80
04570
04571                 LDA ZPOSHI,X            ; Skip z lock-on marker if z >= +$0C** (>= 3072) <KM>
04572                 CMP #12                 ;
04573                 BCS SKIP062             ;
04574
04575                 LDY #$A0                ; Draw z lock-on marker (2 horiz. pixels of COLOR2)
04576                 STY PFMEM.C128R84       ; ...at pixel column 128, row 84 (prep lock-on flag)
04577                 STY PFMEM.C128R85       ; ...at pixel column 128, row 85
04578                 STY PFMEM.C136R84       ; ...at pixel column 136, row 84
04579                 STY PFMEM.C136R85       ; ...at pixel column 136, row 85
04580
04581 SKIP062         STY ISINLOCKON          ; Store lock-on flag (> 0 -> Tracked obj locked on)
04582                 RTS                     ; Return
04583
04584 ;*******************************************************************************
04585 ;*                                                                             *
04586 ;*                                  HYPERWARP                                  *
04587 ;*                                                                             *
04588 ;*                              Handle hyperwarp                               *
04589 ;*                                                                             *
04590 ;*******************************************************************************
04591
04592 ; DESCRIPTION
04593 ;
04594 ; Handles the hyperwarp sequence, which transports our starship from one sector
04595 ; to another. It can be divided into four phases:
04596 ;
04597 ; (1)  ACCELERATION PHASE
04598 ;
04599 ;      The ACCELERATION PHASE is entered after the hyperwarp sequence has been
04600 ;      engaged in subroutine KEYBOARD ($AFFE) by pressing the 'H' key.
04601 ;
04602 ;      The Hyperwarp Target Marker appears and our starship begins to
04603 ;      accelerate. When our starship's velocity reaches 128 <KM/H> (the VELOCITY
04604 ;      readout of the Control Panel Display displays "50"), the STAR TRAIL phase
04605 ;      is entered. 
04606 ;
04607 ;      The Hyperwarp Target Marker is represented by a space object some fixed
04608 ;      distance away in front of our starship as PLAYER3. It has a lifetime of
04609 ;      144 game loop iterations and is tracked. Thus, tracking handling in
04610 ;      subroutine UPDATTCOMP ($A7BF) provides drawing the x and y lock-on
04611 ;      markers in the Attack Computer Display when the Hyperwarp Target Marker
04612 ;      is centered. 
04613 ;
04614 ;      A temporary arrival location on the Galactic Chart was saved when the
04615 ;      hyperwarp was engaged in subroutine KEYBOARD ($AFFE). During the
04616 ;      ACCELERATION PHASE (and the subsequent STAR TRAIL PHASE) this location is
04617 ;      constantly updated depending on how much the Hyperwarp Target Marker
04618 ;      veers off its center position.
04619 ;
04620 ;      The actual arrival hyperwarp marker row and column numbers on the
04621 ;      Galactic Chart are the sum of the temporary arrival hyperwarp marker row
04622 ;      and column numbers stored when engaging the hyperwarp in subroutine
04623 ;      KEYBOARD ($AFFE) and the number of Player/Missile (PM) pixels which the
04624 ;      Hyperwarp Target Marker is off-center vertically and horizontally,
04625 ;      respectively, at the end of the STAR TRAIL PHASE.
04626 ;
04627 ;      NOTE: The used vertical center value of 119 PM pixels is the PM pixel row
04628 ;      number of the top edge of the centered Hyperwarp Target Marker (from top
04629 ;      to bottom: 8 PM pixels to the start of Display List + 16 PM pixels blank
04630 ;      lines + 100 PM pixels to the vertical PLAYFIELD center - 5 PM pixels
04631 ;      relative offset of the Hyperwarp Target Marker's shape center to the
04632 ;      shape's top edge = 119 PM pixels). Recall also that PLAYERs at
04633 ;      single-line resolution have PM pixels that are half as high as they are
04634 ;      wide.
04635 ;
04636 ;      NOTE: The used horizontal center value of 125 PM pixels is the PM pixel
04637 ;      row number of the left edge of the centered Hyperwarp Target Marker (from
04638 ;      left to right: 127 PM pixels to the PLAYFIELD center - 3 PM pixels
04639 ;      relative offset of the Hyperwarp Target Marker's shape center to the
04640 ;      shape's left edge = 125 PM pixels).
04641 ;
04642 ;      If during the ACCELERATION PHASE (and the subsequent STAR TRAIL PHASE)
04643 ;      you switch the Front view to another view, the Hyperwarp Target Marker
04644 ;      changes to a random position which results in arriving at a random
04645 ;      destination sector.
04646 ;
04647 ;      During the ACCELERATION PHASE (and the subsequent STAR TRAIL PHASE) in
04648 ;      all but NOVICE missions, the Hyperwarp Target Marker veers off with
04649 ;      random velocity in x and y direction, which is changed during 6% of game
04650 ;      loop iterations. Table VEERMASKTAB ($BED7) limits the maximum veer-off
04651 ;      velocity depending on the mission level:
04652 ;
04653 ;      +-----------+-----------------------------+
04654 ;      |  Mission  |      Veer-Off Velocity      |
04655 ;      +-----------+-----------------------------+
04656 ;      | NOVICE    |                   0  <KM/H> |
04657 ;      | PILOT     |  -63..-16, +16..+63  <KM/H> |
04658 ;      | WARRIOR   |  -95..-16, +16..+95  <KM/H> |
04659 ;      | COMMANDER | -127..-16, +16..+127 <KM/H> |
04660 ;      +-----------+-----------------------------+
04661 ;
04662 ; (2)  STAR TRAIL PHASE
04663 ;
04664 ;      When our starship's velocity reaches a velocity of 128 <KM/H> (the
04665 ;      VELOCITY readout of the Control Panel Display displays "50"), in addition
04666 ;      to all effects of the ACCELERATION PHASE, multiple star trails begin to
04667 ;      appear while our starship continues to accelerate. Each star trail is
04668 ;      initialized in subroutine INITTRAIL ($A9B4).
04669 ;
04670 ; (3)  HYPERSPACE PHASE
04671 ;
04672 ;      When our starship's velocity reaches a velocity of 254 <KM/H> (the
04673 ;      VELOCITY readout of the Control Panel Display displays "99") our starship
04674 ;      enters the HYPERSPACE PHASE (the VELOCITY readout of the Control Panel
04675 ;      Display displays the infinity symbol).
04676 ;
04677 ;      During the first pass of the HYPERSPACE PHASE the hyperwarp state is set
04678 ;      to HYPERSPACE. This makes the stars and the Hyperwarp Target Marker
04679 ;      disappear in GAMELOOP ($A1F3). Then, the beeper sound pattern HYPERWARP
04680 ;      TRANSIT is played in subroutine BEEP ($B3A6), the hyperwarp distance and
04681 ;      required hyperwarp energy is calculated in subroutine CALCWARP ($B1A7),
04682 ;      and the title line is preloaded with "HYPERSPACE". Code execution returns
04683 ;      via calling subroutine CLEANUPWARP ($A98D) where game variables are
04684 ;      already initialized to their post-hyperwarp values.
04685 ;
04686 ;      During subsequent passes of the HYPERSPACE PHASE, the calculated
04687 ;      hyperwarp energy is decremented in chunks of 10 energy units. Code
04688 ;      execution returns via calling subroutine DECENERGY ($B86F), which
04689 ;      decrements our starship's energy. After the calculated hyperwarp energy
04690 ;      is spent the DECELERATION PHASE is entered.
04691 ;
04692 ; (4)  DECELERATION PHASE
04693 ;
04694 ;      The title line flashes "HYPERWARP COMPLETE", the star field reappears and
04695 ;      our starship decelerates to a stop. The Engines and the hyperwarp are
04696 ;      disengaged and stopped in subroutine ENDWARP ($A987), the arrival
04697 ;      coordinates on the Galactic Chart are initialized, as well as the
04698 ;      vicinity mask.
04699 ;
04700 ;      The vicinity mask limits the position vector components (coordinates) of
04701 ;      space objects in the arrival sector relative to our starship. The
04702 ;      vicinity mask is picked from table VICINITYMASKTAB ($BFB3) by an index
04703 ;      calculated by the arrival y-coordinate modulo 8: The more you have placed
04704 ;      the arrival hyperwarp marker in the vertical center of a sector on the
04705 ;      Galactic Chart, the closer space objects in this sector will be to our
04706 ;      starship. For example, if you placed the arrival hyperwarp marker exactly
04707 ;      in the vertical middle of the sector the index will be 3, thus the space
04708 ;      objects inside the arrival sector will be in the vicinity of <= 4095 <KM>
04709 ;      of our starship. The following table lists the possible coordinates
04710 ;      depending on the calculated index:
04711 ;
04712 ;      +-------+-----------------------+
04713 ;      | Index |    ABS(Coordinate)    |
04714 ;      +-------+-----------------------+
04715 ;      |   0   | <= 65535 ($FF**) <KM> |
04716 ;      |   1   | <= 65535 ($FF**) <KM> |
04717 ;      |   2   | <= 16383 ($3F**) <KM> |
04718 ;      |   3   | <=  4095 ($0F**) <KM> |
04719 ;      |   4   | <= 16383 ($3F**) <KM> |
04720 ;      |   5   | <= 32767 ($7F**) <KM> |
04721 ;      |   6   | <= 65535 ($FF**) <KM> |
04722 ;      |   7   | <= 65535 ($FF**) <KM> |
04723 ;      +-------+-----------------------+
04724 ;
04725 ;      If there is a starbase in the arrival sector, its x and y coordinates are
04726 ;      initialized to random values within the interval defined by the vicinity
04727 ;      mask by using subroutine RNDINVXY ($B7BE). Its z-coordinate is forced to
04728 ;      a value >= +$71** (+28928) <KM>. Its velocity vector components are set
04729 ;      to 0 <KM/H>. 
04730 ;
04731 ;      If there are Zylon ships in the arrival sector then a red alert is
04732 ;      initialized by setting the red alert lifetime to 255 game loop
04733 ;      iterations, playing the beeper sound pattern RED ALERT in subroutine BEEP
04734 ;      ($B3A6) and setting the title phrase to "RED ALERT".
04735
04736 HYPERWARP       LDY WARPSTATE           ; Return if hyperwarp not engaged
04737                 BEQ SKIP066             ;
04738
04739                 LDA VELOCITYLO          ; If velocity >= 254 <KM/H> skip to HYPERSPACE PHASE
04740                 CMP #254                ;
04741                 BCS SKIP067             ;
04742
04743                 CMP #128                ; If velocity < 128 <KM/H> skip to ACCELERATION PHASE
04744                 BCC SKIP063             ;
04745
04746 ;*** STAR TRAIL PHASE **********************************************************
04747                 JSR INITTRAIL           ; Init star trail
04748
04749 ;*** ACCELERATION PHASE ********************************************************
04750 SKIP063         LDA #3                  ; Track Hyperwarp Target Marker (PLAYER3)
04751                 STA TRACKDIGIT          ;
04752
04753                 LDA #SHAP.HYPERWARP     ; PLAYER3 is HYPERWARP TARGET MARKER (shape type 9)
04754                 STA PL3SHAPTYPE         ;
04755                 STA PL3LIFE             ; PLAYER3 lifetime := 144 game loops
04756
04757                 LDA #$1F                ; PLAYER3 z-coordinate := $1F** (7936..8191) <KM>
04758                 STA PL3ZPOSHI           ;
04759
04760                 SEC                     ; New arrival hyperwarp marker row number is...
04761                 LDA PL3ROWNEW           ; WARPARRVROW := WARPTEMPROW + PL3ROWNEW...
04762                 SBC #119                ; ... - 119 PM pixels (top edge of centered...
04763                 CLC                     ; ...Hyperwarp Target Marker)
04764                 ADC WARPTEMPROW         ;
04765                 AND #$7F                ; Limit WARPARRVROW to 0..127
04766                 STA WARPARRVROW         ;
04767
04768                 SEC                     ; New arrival hyperwarp marker column number is...
04769                 LDA PL3COLUMN           ; WARPARRVCOLUMN := WARPTEMPCOLUMN + PL3COLUMN...
04770                 SBC #125                ; ... - 125 PM pixels (left edge of centered...
04771                 CLC                     ; ...Hyperwarp Target Marker)
04772                 ADC WARPTEMPCOLUMN      ;
04773                 AND #$7F                ; Limit WARPARRVCOLUMN to 0..127
04774                 STA WARPARRVCOLUMN      ;
04775
04776                 LDA MISSIONLEVEL        ; Skip if NOVICE mission
04777                 BEQ SKIP065             ;
04778
04779                 LDA RANDOM              ; Prep random number
04780                 LDY SHIPVIEW            ; Skip if in Front view
04781                 BEQ SKIP064             ;
04782
04783                 STA PL3COLUMN           ; Randomize PM pixel row and column number...
04784                 STA PL3ROWNEW           ; ...of Hyperwarp Target Marker
04785
04786 SKIP064         CMP #16                 ; Return in 94% (240:256) of game loops
04787                 BCS SKIP066             ;
04788
04789 ;*** Veer off Hyperwarp Target Marker and return *******************************
04790 SKIP065         LDA RANDOM              ; Prep random x-velocity of Hyperwarp Target Marker
04791                 ORA #$10                ; Velocity value >= 16 <KM/H>
04792                 AND VEERMASK            ; Limit velocity value by mission level
04793                 STA PL3XVEL             ; PLAYER3 x-velocity := velocity value
04794
04795                 LDA RANDOM              ; Prep random y-velocity of Hyperwarp Target Marker
04796                 ORA #$10                ; Velocity value >= 16 <KM/H>
04797                 AND VEERMASK            ; Limit velocity value by mission level
04798                 STA PL3YVEL             ; PLAYER3 y-velocity := velocity value
04799 SKIP066         RTS                     ; Return
04800
04801 ;*** HYPERSPACE PHASE **********************************************************
04802 SKIP067         TYA                     ; Skip if already in HYPERSPACE PHASE
04803                 BMI SKIP068             ;
04804
04805 ;*** HYPERSPACE PHASE (First pass) *********************************************
04806                 LDA #$FF                ; Set hyperwarp state to HYPERSPACE PHASE
04807                 STA WARPSTATE           ;
04808
04809                 LDX #$00                ; Play beeper sound pattern HYPERWARP TRANSIT
04810                 JSR BEEP                ;
04811
04812                 JSR CALCWARP            ; Calc hyperwarp energy
04813
04814                 LDY #$1B                ; Prep title phrase "HYPERSPACE"
04815                 JMP CLEANUPWARP         ; Return via CLEANUPWARP
04816
04817 ;*** HYPERSPACE PHASE (Second and later passes) ********************************
04818 SKIP068         DEC WARPENERGY          ; Decrement energy in chunks of 10 energy units
04819                 BEQ SKIP069             ; Skip to DECELERATION PHASE if hyperwarp energy zero
04820
04821                 LDX #2                  ; ENERGY := ENERGY - 10 and return
04822                 JMP DECENERGY           ;
04823
04824 ;*** DECELERATION PHASE ********************************************************
04825 SKIP069         LDY #$19                ; Prep title phrase "HYPERWARP COMPLETE"
04826                 JSR ENDWARP             ; Stop our starship
04827
04828                 LDA WARPARRVCOLUMN      ; Make the arrival hyperwarp marker column number...
04829                 STA WARPDEPRCOLUMN      ; ...the departure hyperwarp marker column number
04830                 LDA WARPARRVROW         ; Make the arrival hyperwarp marker row number...
04831                 STA WARPDEPRROW         ; ...the departure hyperwarp marker row number
04832
04833                 LSR A                   ; B3..1 of arrival hyperwarp marker row number...
04834                 AND #$07                ; ...pick vicinity mask
04835                 TAX                     ;
04836                 LDA VICINITYMASKTAB,X   ;
04837                 STA VICINITYMASK        ; Store vicinity mask (limits space obj coordinates)
04838
04839                 LDY ARRVSECTOR          ; Make the arrival sector the current sector
04840                 STY CURRSECTOR          ;
04841
04842 ;*** Init starbase in arrival sector *******************************************
04843                 LDA #0                  ; Clear starbase-in-sector flag
04844                 STA ISSTARBASESECT      ;
04845
04846                 LDX GCMEMMAP,Y          ; Skip if no starbase in arrival sector
04847                 BPL SKIP070             ;
04848
04849                 LDA #$FF                ; Set starbase-in-sector flag
04850                 STA ISSTARBASESECT      ;
04851
04852 ;*** Set position vector and velocity vector of starbase ***********************
04853                 LDY #0                  ;
04854 LOOP033         LDA #0                  ; Loop over all coordinates of starbase
04855                 STA PL2ZVEL,Y           ; Starbase velocity vector component := 0 <KM/H>
04856                 LDA #1                  ;
04857                 STA PL2ZPOSSIGN,Y       ; Starbase coordinate sign := + (positive)
04858                 LDA RANDOM              ; Prep random number...
04859                 AND VICINITYMASK        ; ...limit number range by vicinity mask, then...
04860                 STA PL2ZPOSHI,Y         ; ...store in starbase coordinate (high byte)
04861
04862                 TYA                     ;
04863                 CLC                     ;
04864                 ADC #NUMSPCOBJ.ALL      ;
04865                 TAY                     ;
04866                 CMP #NUMSPCOBJ.ALL*3    ;
04867                 BCC LOOP033             ; Next starbase coordinate
04868
04869                 LDA PL2ZPOSHI           ; Force starbase z-coordinate >= +$71** <KM>
04870                 ORA #$71                ;
04871                 STA PL2ZPOSHI           ;
04872                 LDX #2                  ; Randomly invert starbase x and y coordinates...
04873                 JMP RNDINVXY            ; ...and return
04874
04875 ;*** Flash red alert if Zylon sector entered ***********************************
04876 SKIP070         BEQ SKIP071             ; Skip if no Zylon ships in sector
04877
04878                 LDA #255                ; Red alert lifetime := 255 game loops
04879                 STA REDALERTLIFE        ;
04880
04881                 LDX #$06                ; Play beeper sound pattern RED ALERT
04882                 JSR BEEP                ;
04883
04884                 LDY #$75                ; Set title phrase "RED ALERT"
04885                 JSR SETTITLE            ;
04886
04887 SKIP071         RTS                     ; Return
04888
04889 ;*******************************************************************************
04890 ;*                                                                             *
04891 ;*                                  ABORTWARP                                  *
04892 ;*                                                                             *
04893 ;*                               Abort hyperwarp                               *
04894 ;*                                                                             *
04895 ;*******************************************************************************
04896
04897 ; DESCRIPTION
04898 ;
04899 ; Aborts hyperwarp.
04900 ;
04901 ; This subroutine is entered from subroutine KEYBOARD ($AFFE). It subtracts 100
04902 ; energy units for aborting the hyperwarp and preloads the title phrase with
04903 ; "HYPERWARP ABORTED". Code execution continues into subroutine ENDWARP
04904 ; ($A987). 
04905
04906 ABORTWARP       LDX #1                  ; ENERGY := ENERGY - 100 after hyperwarp abort
04907                 JSR DECENERGY           ;
04908
04909                 LDY #$17                ; Prep title phrase "HYPERWARP ABORTED"
04910
04911 ;*******************************************************************************
04912 ;*                                                                             *
04913 ;*                                   ENDWARP                                   *
04914 ;*                                                                             *
04915 ;*                                End hyperwarp                                *
04916 ;*                                                                             *
04917 ;*******************************************************************************
04918
04919 ; DESCRIPTION
04920 ;
04921 ; Ends hyperwarp.
04922 ;
04923 ; This subroutine stops our starship's Engines and resets the hyperwarp state.
04924 ; Code execution continues into subroutine CLEANUPWARP ($A98D).
04925
04926 ENDWARP         LDA #0                  ; Stop Engines
04927                 STA NEWVELOCITY         ;
04928                 STA WARPSTATE           ; Disengage hyperwarp
04929
04930 ;*******************************************************************************
04931 ;*                                                                             *
04932 ;*                                 CLEANUPWARP                                 *
04933 ;*                                                                             *
04934 ;*                        Clean up hyperwarp variables                         *
04935 ;*                                                                             *
04936 ;*******************************************************************************
04937
04938 ; DESCRIPTION
04939 ;
04940 ; Cleans up after a hyperwarp.
04941 ;
04942 ; This subroutine restores many hyperwarp related variables to their
04943 ; post-hyperwarp values: The number of used space objects is set to the regular
04944 ; value of 16 (5 PLAYER space objects + 12 PLAYFIELD space objects (stars),
04945 ; counted 0..16), our starship's velocity (high byte) is cleared as well as the
04946 ; explosion lifetime, the hit badness, the PLAYER3 shape type (Hyperwarp Target
04947 ; Marker), the Engines energy drain rate, and the lifetimes of the PLAYERs. The
04948 ; docking state is reset as well as the tracking digit. The title phrase is
04949 ; updated with either "HYPERSPACE" or "HYPERWARP ABORTED".
04950 ;
04951 ; INPUT
04952 ;
04953 ;   Y = Title phrase offset. Used values are: 
04954 ;     $17 -> "HYPERWARP ABORTED"
04955 ;     $1B -> "HYPERSPACE"
04956
04957 CLEANUPWARP     LDA #NUMSPCOBJ.NORM-1   ; Set normal number of space objects
04958                 STA MAXSPCOBJIND        ; (5 PLAYER spc objs + 12 PLAYFIELD spc objs (stars))
04959
04960                 LDA #0                  ;
04961                 STA VELOCITYHI          ; Turn off hyperwarp velocity
04962                 STA EXPLLIFE            ; Explosion lifetime := 0 game loops
04963                 STA HITBADNESS          ; HITBADNESS := NO HIT
04964                 STA PL3SHAPTYPE         ; Clear PLAYER3 shape type
04965                 STA DRAINENGINES        ; Clear Engines energy drain rate
04966                 CPY #$17                ; Skip if hyperwarp was aborted
04967                 BEQ SKIP072             ;
04968
04969                 STA PL0LIFE             ; Zylon ship 0 lifetime := 0 game loops
04970                 STA PL1LIFE             ; Zylon ship 1 lifetime := 0 game loops
04971
04972 SKIP072         STA PL2LIFE             ; Zylon photon torpedo lifetime := 0 game loops
04973                 STA PL3LIFE             ; Hyperwarp Target Marker lifetime := 0 game loops
04974                 STA PL4LIFE             ; Photon torpedo 1 lifetime := 0  game loops
04975                 STA DOCKSTATE           ; DOCKSTATE := NO DOCKING
04976                 STA TRACKDIGIT          ; Clear index of tracked space object
04977                 JMP SETTITLE            ; Set title phrase and return
04978
04979 ;*******************************************************************************
04980 ;*                                                                             *
04981 ;*                                  INITTRAIL                                  *
04982 ;*                                                                             *
04983 ;*         Initialize star trail during STAR TRAIL PHASE of hyperwarp          *
04984 ;*                                                                             *
04985 ;*******************************************************************************
04986
04987 ; DESCRIPTION
04988 ;
04989 ; BACKGROUND
04990 ;
04991 ; Star trails are displayed during the STAR TRAIL PHASE, that is, after the
04992 ; ACCELERATION PHASE and before the HYPERSPACE PHASE of the hyperwarp. 
04993 ;
04994 ; A star trail is formed by 6 stars represented by 6 PLAYFIELD space objects
04995 ; with continuous position vector indices in 17..48 (indices are wrapped around
04996 ; when greater than 48). Between the creations of two star trails there is delay
04997 ; of 4 game loop iterations.
04998 ;
04999 ; DETAILS
05000 ;
05001 ; This subroutine first decrements this star trail creation delay, returning if
05002 ; the delay is still counting down. If the delay falls below 0 then it continues
05003 ; accelerating our starship's velocity toward hyperwarp speed and then creates a
05004 ; new star trail:
05005 ;
05006 ; First, it raises the maximum index of used space objects to 48 (increasing the
05007 ; number of displayed space objects to 49), resets the star trail creation delay
05008 ; to 4 game loop iterations, and then forms a new star trail of 6 stars
05009 ; represented by 6 PLAYFIELD space objects. The x and y coordinates for all 6
05010 ; stars are the same, picked randomly from tables WARPSTARXTAB ($BB3A) and
05011 ; WARPSTARYTAB ($BB3E), respectively, with their signs changed randomly. Their
05012 ; z-coordinates are computed in increasing depth from at least +4608 (+$12**)
05013 ; <KM> in intervals of +80 (+$0050) <KM>. Their velocity vector components are
05014 ; set to 0 <KM/H>.
05015
05016 L.RANGE         = $68                   ; z-coordinate of star in star trail (16-bit value)
05017 L.TRAILCNT      = $6E                   ; Star's index in star trail. Used values are: 0..5.
05018
05019 INITTRAIL       DEC TRAILDELAY          ; Decrement star trail delay
05020                 BPL SKIP074             ; Return if delay still counting
05021
05022                 LDA #1                  ; Turn on hyperwarp velocity
05023                 STA VELOCITYHI          ;
05024
05025                 LDA #NUMSPCOBJ.ALL-1    ; Max index of space objects (for star trail stars)
05026                 STA MAXSPCOBJIND        ;
05027
05028                 LDA #3                  ; Star trail delay := 3(+1) game loops
05029                 STA TRAILDELAY          ;
05030
05031                 LDX TRAILIND            ; Next avail. space obj index for star of star trail
05032
05033                 LDA #$12                ; Star z-coordinate := >= +$12** (+4608) <KM>
05034                 STA L.RANGE+1           ;
05035
05036                 LDA RANDOM              ; Calc random index to pick initial star coordinates
05037                 AND #$03                ;
05038                 TAY                     ;
05039                 LDA WARPSTARXTAB,Y      ; Pick x-coordinate (high byte) of star from table
05040                 STA XPOSHI,X            ;
05041                 LDA WARPSTARYTAB,Y      ;
05042                 STA YPOSHI,X            ; Pick y-coordinate (high byte) of star from table
05043                 JSR RNDINVXY            ; Randomize signs of x and y coordinates of star
05044
05045                 TXA                     ; Save space object index
05046                 TAY                     ;
05047                 LDA #5                  ; Loop over 5(+1) stars that form the star trail
05048                 STA L.TRAILCNT          ; Store star counter of star trail
05049
05050 LOOP034         CLC                     ; Place stars in z-coordinate intervals of +80 <KM>
05051                 LDA L.RANGE             ;
05052                 ADC #80                 ;
05053                 STA L.RANGE             ;
05054                 STA ZPOSLO,X            ;
05055                 LDA L.RANGE+1           ;
05056                 ADC #0                  ;
05057                 STA L.RANGE+1           ;
05058                 STA ZPOSHI,X            ;
05059
05060                 LDA #0                  ; Star's velocity vector components := 0 <KM/H>
05061                 STA ZVEL,X              ;
05062                 STA XVEL,X              ;
05063                 STA YVEL,X              ;
05064                 LDA #1                  ; Star's z-coordinate sign := + (= ahead of starship)
05065                 STA ZPOSSIGN,X          ;
05066
05067                 LDA #99                 ; Init pixel row and column numbers to magic...
05068                 STA PIXELROWNEW,X       ; ...offscreen value (triggers automatic recalc in...
05069                 STA PIXELCOLUMN,X       ; ...GAMELOOP's calls to SCREENCOLUMN and SCREENROW)
05070
05071                 JSR COPYPOSXY           ; Copy x and y coordinate from previous star in trail
05072
05073                 DEX                     ; Decrement space object index to next star
05074                 CPX #NUMSPCOBJ.NORM     ; If index reaches minimum value...
05075                 BCS SKIP073             ;
05076                 LDX #NUMSPCOBJ.ALL-1    ; ...wrap-around to maximum space object index
05077 SKIP073         DEC L.TRAILCNT          ;
05078                 BPL LOOP034             ; Next star of star trail
05079
05080                 STX TRAILIND            ; Save space object index of star trail's last star
05081 SKIP074         RTS                     ; Return
05082
05083 ;*******************************************************************************
05084 ;*                                                                             *
05085 ;*                                 PROJECTION                                  *
05086 ;*                                                                             *
05087 ;*         Calculate pixel column (or row) number from position vector         *
05088 ;*                                                                             *
05089 ;*******************************************************************************
05090
05091 ; Calculates the pixel column (or row) number of a position vector x (or y)
05092 ; component relative to the PLAYFIELD center by computing the perspective
05093 ; projection quotient
05094 ;
05095 ;     QUOTIENT := DIVIDEND / DIVISOR * 128
05096 ;
05097 ; with
05098 ;
05099 ;     DIVIDEND := ABS(x-coordinate (or y-coordinate)) / 2
05100 ;     DIVISOR  := ABS(z-coordinate) / 2  
05101 ;
05102 ; If the QUOTIENT is in 0..255, it is used as an index to pick the pixel column
05103 ; (or row) number from table MAPTO80 ($0DE9), returning values in 0..80.
05104 ;
05105 ; If the QUOTIENT is larger than 255 ("dividend overflow") or if the
05106 ; z-coordinate = 0 ("division by zero") then the error value 255 is returned.
05107 ;
05108 ; INPUT
05109 ;
05110 ;   X                   = Position vector index. Used values are: 0..48.
05111 ;   DIVIDEND ($6A..$6B) = Dividend (positive 16-bit value), contains the
05112 ;                         absolute value of the x (or y) coordinate.
05113 ;
05114 ; OUTPUT
05115 ;
05116 ;   A = Pixel column (or row) number relative to PLAYFIELD center. Used values
05117 ;       are: 
05118 ;     0..80 -> Pixel number
05119 ;     255   -> Error value indicating "dividend overflow" or "division by zero"
05120
05121 L.DIVISOR       = $68                   ; Divisor (16-bit value)
05122 L.QUOTIENT      = $6D                   ; Division result (unsigned 8-bit value)
05123 L.LOOPCNT       = $6E                   ; Division loop counter. Used values are: 7..0.
05124
05125 PROJECTION      LDA #0                  ; Init quotient result
05126                 STA L.QUOTIENT          ;
05127
05128                 LDA #7                  ; Init division loop counter
05129                 STA L.LOOPCNT           ;
05130
05131                 LSR DIVIDEND+1          ; DIVIDEND := x-coordinate (or y-coordinate) / 2
05132                 ROR DIVIDEND            ; (division by 2 to make B15 = 0?) (?)
05133
05134                 LDA SHIPVIEW            ; Skip if in Aft view
05135                 BNE SKIP075             ;
05136
05137                 LDA ZPOSHI,X            ; If in Front view -> DIVISOR := z-coordinate / 2
05138                 LSR A                   ; (division by 2 to make B15 = 0?) (?)
05139                 STA L.DIVISOR+1         ;
05140                 LDA ZPOSLO,X            ;
05141                 ROR A                   ;
05142                 STA L.DIVISOR           ;
05143                 JMP LOOP035             ;
05144
05145 SKIP075         SEC                     ; If in Aft view -> DIVISOR := - z-coordinate / 2
05146                 LDA #0                  ; (division by 2 to make B15 = 0?) (?)
05147                 SBC ZPOSLO,X            ;
05148                 STA L.DIVISOR           ;
05149                 LDA #0                  ;
05150                 SBC ZPOSHI,X            ;
05151                 LSR A                   ;
05152                 STA L.DIVISOR+1         ;
05153                 ROR L.DIVISOR           ;
05154
05155 LOOP035         ASL L.QUOTIENT          ; QUOTIENT := DIVIDEND / DIVISOR * 128
05156                 SEC                     ;
05157                 LDA DIVIDEND            ;
05158                 SBC L.DIVISOR           ;
05159                 TAY                     ;
05160                 LDA DIVIDEND+1          ;
05161                 SBC L.DIVISOR+1         ;
05162                 BCC SKIP076             ;
05163
05164                 STA DIVIDEND+1          ;
05165                 STY DIVIDEND            ;
05166                 INC L.QUOTIENT          ;
05167
05168 SKIP076         ASL DIVIDEND            ;
05169                 ROL DIVIDEND+1          ;
05170                 BCC SKIP077             ;
05171
05172                 LDA #255                ; Return 255 if division by zero or dividend overflow
05173                 RTS                     ;
05174
05175 SKIP077         DEC L.LOOPCNT           ;
05176                 BPL LOOP035             ; Next division loop iteration
05177
05178                 LDY L.QUOTIENT          ; Prep with quotient
05179                 LDA MAPTO80,Y           ; Pick and return pixel column (or row) number...
05180 SKIP078         RTS                     ; ...relative to PLAYFIELD center
05181
05182 ;*******************************************************************************
05183 ;*                                                                             *
05184 ;*                                  MANEUVER                                   *
05185 ;*                                                                             *
05186 ;*     Maneuver our starship's and Zylon photon torpedoes and Zylon ships      *
05187 ;*                                                                             *
05188 ;*******************************************************************************
05189
05190 ; DESCRIPTION
05191 ;
05192 ; This subroutine maneuvers both of our starship's photon torpedoes, the single
05193 ; Zylon photon torpedo, and the one or two Zylon ships that are simultaneously
05194 ; displayed on the screen. It also creates meteors and new Zylon ships. This
05195 ; subroutine is executed only if our starship is not in a starbase sector and
05196 ; hyperwarp is not engaged.
05197 ;
05198 ; BACKGROUND
05199 ;
05200 ; When a Zylon ship is initialized, a "flight pattern" is assigned to it. There
05201 ; are 3 flight patterns (0, 1, and 4) which are picked from table ZYLONFLPATTAB
05202 ; ($BF91).
05203 ;
05204 ; The flight pattern determines the maximum velocity with which a Zylon ship can
05205 ; move along each axis of the 3D coordinate system, that is, the maximum value
05206 ; of a velocity vector component. Velocity vector components for Zylon ships are
05207 ; picked from the Zylon velocity table ZYLONVELTAB ($BF99):
05208 ;
05209 ; +-----------------+-----+-----+-----+-----+-----+-----+-----+-----+
05210 ; | Velocity Index  |  0  |  1  |  2  |  3  |  4  |  5  |  6  |  7  |
05211 ; +-----------------+-----+-----+-----+-----+-----+-----+-----+-----+
05212 ; | Velocity <KM/H> | +62 | +30 | +16 |  +8 |  +4 |  +2 |  +1 |  0  |
05213 ; +-----------------+-----+-----+-----+-----+-----+-----+-----+-----+
05214 ; +-----------------+-----+-----+-----+-----+-----+-----+-----+-----+
05215 ; | Velocity Index  |  8  |  9  |  10 |  11 |  12 |  13 |  14 |  15 |
05216 ; +-----------------+-----+-----+-----+-----+-----+-----+-----+-----+
05217 ; | Velocity <KM/H> |  0  |  -1 |  -2 |  -4 |  -8 | -16 | -30 | -62 |
05218 ; +-----------------+-----+-----+-----+-----+-----+-----+-----+-----+
05219 ;
05220 ; The index into the Zylon velocity table ZYLONVELTAB ($BF99) corresponding to
05221 ; the maximum velocity is called the "maximum velocity index". The following
05222 ; table shows the flight patterns, their maximum velocity indices, and their
05223 ; corresponding velocities:
05224 ;
05225 ; +----------------+------------------+------------------+
05226 ; | Flight Pattern | Maximum Velocity | Maximum Velocity |
05227 ; |                |      Index       |                  |
05228 ; +----------------+------------------+------------------+
05229 ; |       0        |         0        |    +62 <KM/H>    |
05230 ; |       0        |        15        |    -62 <KM/H>    |
05231 ; |       1        |         1        |    +30 <KM/H>    |
05232 ; |       1        |        14        |    -30 <KM/H>    |
05233 ; |       4        |         4        |     +4 <KM/H>    |
05234 ; |       4        |        11        |     -4 <KM/H>    |
05235 ; +----------------+------------------+------------------+
05236 ;
05237 ; Because flight pattern 0 produces the fastest-moving Zylon ships, which
05238 ; maneuver aggressively, it is called the "attack flight pattern".
05239 ;
05240 ; Each Zylon ship has a set of 3 maximum velocity indices, one for each of its
05241 ; velocity vector components.
05242 ;
05243 ; Each Zylon ship has also one more set of 3 velocity indices, called "Zylon
05244 ; velocity indices", one for each of its velocity vector components. They are
05245 ; used to pick the current values of the velocity vector components from the
05246 ; Zylon velocity table ZYLONVELTAB ($BF99).
05247 ;
05248 ; In order to maneuver Zylon ships this subroutine uses the concept of
05249 ; "milestone velocity indices". By using delay timers, called "Zylon timers",
05250 ; this subroutine gradually increases or decreases the Zylon velocity indices
05251 ; with every game loop iteration to eventually match the corresponding milestone
05252 ; velocity indices. By incrementing a Zylon velocity index a Zylon ship
05253 ; accelerates toward the negative direction of a coordinate axis. By
05254 ; decrementing a Zylon velocity index a Zylon ship accelerates toward the
05255 ; positive direction of a coordinate axis. If one milestone velocity index is
05256 ; matched or a "milestone timer" has counted down to 0, a new milestone velocity
05257 ; index is calculated and the matching of the current Zylon velocity indices
05258 ; with the new milestone velocity indices repeats.
05259 ;
05260 ; DETAILS
05261 ;
05262 ; For quick lookup, the following table lists the PLAYERs and what space objects
05263 ; they represent in this subroutine:
05264 ;
05265 ; +--------+---------------------------------+
05266 ; | PLAYER |           Represents            |
05267 ; +--------+---------------------------------+
05268 ; |    0   | Zylon Ship 0                    |
05269 ; |    1   | Zylon Ship 1                    |
05270 ; |    2   | Zylon Photon Torpedo, Meteor    |
05271 ; |    3   | Our starship's Photon Torpedo 0 |
05272 ; |    4   | Our starship's Photon Torpedo 1 |
05273 ; +--------+---------------------------------+
05274 ;
05275 ; This subroutine executes the following steps:
05276 ;
05277 ; (1)  Update the x and y velocity vector components of both of our starship's
05278 ;      photon torpedoes 0 and 1.
05279 ;
05280 ;      The x and y velocity vector components of both of our starship's photon
05281 ;      torpedoes 0 and 1 are only updated if they are tracking (homing in on) a
05282 ;      target.
05283 ;
05284 ;      To update the y-velocity vector components of both of our starship's
05285 ;      photon torpedoes 0 and 1 the PLAYER row number difference between the
05286 ;      PLAYER of tracked target space object and the current location of the
05287 ;      PLAYER of our starship's photon torpedo 0 is passed to subroutine
05288 ;      HOMINGVEL ($AECA). It returns the new y-velocity vector component value
05289 ;      for both of our starship's photon torpedoes in <KM/H>. If the target is
05290 ;      located below our starship's photon torpedo 0 a value of 0 <KM/H> is
05291 ;      used.
05292 ;
05293 ;      NOTE: The new y-velocity vector components depend only on the PLAYER row
05294 ;      number of our starship's photon torpedo 0.
05295 ;
05296 ;      To update the x-velocity vector components of both of our starship's
05297 ;      photon torpedoes, the above calculation is repeated for the PLAYER column
05298 ;      numbers of each of our starship's photon torpedoes 0 and 1.
05299 ;
05300 ; (2)  Make the Zylon ships follow the rotation of our starship.
05301 ;
05302 ;      If you rotate our starship away from Zylon ships they adjust their course
05303 ;      such that they reappear in our starship's view.
05304 ;
05305 ;      This is achieved by 4 Zylon timers, one for each of both Zylon ships'
05306 ;      current x and y Zylon velocity indices. The Zylon timers are decremented
05307 ;      every game loop iteration. If any of them reach a value of 0, the
05308 ;      corresponding Zylon velocity index is incremented or decremented
05309 ;      depending on the current joystick position.
05310 ;
05311 ;      For example, if the Zylon timer for the x-velocity of Zylon ship 0
05312 ;      reaches 0 and at the same time the joystick is pushed left then the
05313 ;      x-Zylon velocity index of this Zylon ship is incremented. This
05314 ;      accelerates the Zylon ship toward negative x-direction ("left"): The
05315 ;      Zylon ship follows our starship's rotation. This works in Aft view, too,
05316 ;      where the direction of change of the Zylon velocity index is reversed.
05317 ;      After setting the new Zylon velocity index, it is used to pick a new
05318 ;      Zylon timer value for this Zylon velocity index: 
05319 ;
05320 ;      +--------------------------------+----+----+----+----+----+----+----+----+
05321 ;      | Velocity Index                 |  0 |  1 |  2 |  3 |  4 |  5 |  6 |  7 |
05322 ;      +--------------------------------+----+----+----+----+----+----+----+----+
05323 ;      | Zylon Timer Value (Game Loops) |  0 |  2 |  4 |  6 |  8 | 10 | 12 | 14 |
05324 ;      +--------------------------------+----+----+----+----+----+----+----+----+
05325 ;      +--------------------------------+----+----+----+----+----+----+----+----+
05326 ;      | Velocity Index                 |  8 |  9 | 10 | 11 | 12 | 13 | 14 | 15 |
05327 ;      +--------------------------------+----+----+----+----+----+----+----+----+
05328 ;      | Zylon Timer Value (Game Loops) | 14 | 12 | 10 |  8 |  6 |  4 |  2 |  0 |
05329 ;      +--------------------------------+----+----+----+----+----+----+----+----+
05330 ;
05331 ; (3)  Update the x and y velocity vector components of the single Zylon photon
05332 ;      torpedo.
05333 ;
05334 ;      If a Zylon photon torpedo is moving toward our starship then update its x
05335 ;      and y velocity vector components. They are picked from table
05336 ;      ZYLONHOMVELTAB ($BF85) and depend on the mission level. The signs of the
05337 ;      velocity vector components are always set such that the Zylon photon
05338 ;      torpedo is guided toward our starship. 
05339 ;
05340 ; (4)  Create a meteor?
05341 ;
05342 ;      If PLAYER2, the PLAYER to represent a meteor, is either initial or not
05343 ;      alive, then attempt in 7 out of 8 game loop iterations to create a new
05344 ;      meteor. 
05345 ;
05346 ;      With a probability of 2% (4:256) a new meteor is created: Its shape type
05347 ;      is set to METEOR, its position vector components to random coordinates in
05348 ;      subroutine INITPOSVEC ($B764), its lifetime to 60 game loop iterations,
05349 ;      and its velocity vector components (velocities) to x-velocity: 0 <KM/H>,
05350 ;      y-velocity: 0 <KM/H>, z-velocity: -8 <KM/H>. Then code execution returns.
05351 ;
05352 ; (5)  Toggle Zylon ship control.
05353 ;
05354 ;      Every other game loop iteration, the game takes control of and maneuvers
05355 ;      the other Zylon ship.
05356 ;
05357 ; (6)  Create new Zylon ship?
05358 ;
05359 ;      If the game-controlled Zylon ship is not alive, check if both Zylon ships
05360 ;      are not alive and this is an empty sector. If so, then attempt to create
05361 ;      a meteor. Otherwise create a new Zylon ship with infinite lifetime.
05362 ;      Randomly pick its shape type from table ZYLONSHAPTAB ($BF89) (ZYLON
05363 ;      BASESTAR, ZYLON CRUISER, or ZYLON FIGHTER) and its flight pattern from
05364 ;      table ZYLONFLPATTAB ($BF91) (attack flight pattern 0 is always picked in
05365 ;      a NOVICE mission). Then set the milestone timer to 1 game loop iteration
05366 ;      and the position vector of the Zylon ship to a position of at least
05367 ;      +28928 (+$71**) <KM> in front of our starship. The y-coordinate depends
05368 ;      on the value of VICINITYMASK ($C7). The x-coordinate is the sum of the
05369 ;      y-coordinate plus at least 4864..5119 ($13**) <KM>. Randomly choose the
05370 ;      signs of the x and y coordinates.
05371 ;
05372 ; (7)  Set the current flight pattern to attack flight pattern?
05373 ;
05374 ;      The current flight pattern of the Zylon ship will change to attack flight
05375 ;      pattern if it is close enough (z-coordinate < +8192 (+$20**) <KM>) and
05376 ;      one of the following conditions is met:
05377 ;
05378 ;      o   The Zylon ship is located behind our starship.
05379 ;
05380 ;      o   The shape of the Zylon ship is not initial and does not currently
05381 ;          appear as a blip in the Long-Range Scan view.
05382 ;
05383 ; (8)  Update the back-attack flag and the milestone velocity indices.
05384 ;
05385 ;      The milestone timer is decremented for the game-controlled Zylon ship. If
05386 ;      this timer reaches a value of 0 the following steps are executed:
05387 ;
05388 ;      o   The milestone timer is reset to a value of 120 game loop iterations.
05389 ;
05390 ;      o   The back-attack flag is updated. It determines if the game-controlled
05391 ;          Zylon ship not only attacks from the front of our starship but also
05392 ;          from the back. A back-attack takes place with a probability of 19%
05393 ;          (48:256) in WARRIOR or COMMANDER missions.
05394 ;
05395 ;      o   Course corrections are prepared for the game-controlled Zylon ship by
05396 ;          computing the new milestone vector indices, resulting in new velocity
05397 ;          vector components for this Zylon ship. The new milestone velocity
05398 ;          indices for each velocity vector component are randomly chosen
05399 ;          depending of the flight pattern. Recall that the Zylon velocity index
05400 ;          is changed gradually to match the milestone velocity index. It
05401 ;          corresponds to a maximum velocity vector component when using this
05402 ;          index to pick a velocity vector component from Zylon velocity table
05403 ;          ZYLONVELTAB ($BF99):
05404 ;
05405 ;          +----------------+----------------+------------------+
05406 ;          | Flight Pattern | New Milestone  | Maximum Velocity |
05407 ;          |                | Velocity Index | Vector Component |
05408 ;          +----------------+----------------+------------------+
05409 ;          |       0        |        0       |    +62 <KM/H>    |
05410 ;          |       0        |       15       |    -62 <KM/H>    |
05411 ;          |       1        |        1       |    +30 <KM/H>    |
05412 ;          |       1        |       14       |    -30 <KM/H>    |
05413 ;          |       4        |        4       |     +4 <KM/H>    |
05414 ;          |       4        |       11       |     -4 <KM/H>    |
05415 ;          +----------------+----------------+------------------+
05416 ;
05417 ; (9)  Update milestone velocity indices in attack flight pattern.
05418 ;
05419 ;      If a Zylon ship executes the attack flight pattern, its milestone
05420 ;      velocity indices are changed depending on the current location of the
05421 ;      Zylon ship as follows:
05422 ;
05423 ;      +--------------+-------------+----------------+------------+----------------+
05424 ;      | x-Coordinate |  Where on   |   Milestone    |  Velocity  | Zylon Ship     |
05425 ;      |              |   Screen    | Velocity Index |            | Accelerates... |
05426 ;      +--------------+-------------+----------------+------------+----------------+
05427 ;      | x <  0 <KM>  | left half   |       0        | +62 <KM/H> | to the right   |
05428 ;      | x >= 0 <KM>  | right half  |      15        | -62 <KM/H> | to the left    |
05429 ;      +--------------+-------------+----------------+------------+----------------+
05430 ;      +--------------+-------------+----------------+------------+----------------+
05431 ;      | y-Coordinate |  Where on   |   Milestone    |  Velocity  | Zylon Ship     |
05432 ;      |              |   Screen    | Velocity Index |            | Accelerates... |
05433 ;      +--------------+-------------+----------------+------------+----------------+
05434 ;      | y <  0 <KM>  | bottom half |       0        | +62 <KM/H> | up             |
05435 ;      | y >= 0 <KM>  | top half    |      15        | -62 <KM/H> | down           |
05436 ;      +--------------+-------------+----------------+------------+----------------+
05437 ;
05438 ;      Thus, with respect to its x and y coordinates, the Zylon ship oscillates
05439 ;      around the center of the Front or Aft view.
05440 ;
05441 ;      This is the behavior of the Zylon ship along the z-axis:
05442 ;
05443 ;      If the Zylon ship attacks from the front:
05444 ;
05445 ;      +--------------------------+----------------+------------+----------------+
05446 ;      |       z-Coordinate       |   Milestone    |  Velocity  | Zylon Ship     |
05447 ;      |                          | Velocity Index |            | Accelerates... |
05448 ;      +--------------------------+----------------+------------+----------------+
05449 ;      | z <  +2560 (+$0A00) <KM> |       0        | +62 <KM/H> | outbound       |
05450 ;      | z >= +2560 (+$0A00) <KM> |      15        | -62 <KM/H> | inbound        |
05451 ;      +--------------------------+----------------+------------+----------------+
05452 ;
05453 ;      In other words, the Zylon ship accelerates into positive z-direction
05454 ;      (outbound) up to a distance of +2560 (+$0A00) <KM>, then reverses its
05455 ;      course and returns back to our starship (inbound).
05456 ;
05457 ;      If the Zylon ship attacks from the back:
05458 ;
05459 ;      +--------------------------+----------------+------------+----------------+
05460 ;      |       z-Coordinate       |   Milestone    |  Velocity  | Zylon Ship     |
05461 ;      |                          | Velocity Index |            | Accelerates... |
05462 ;      +--------------------------+----------------+------------+----------------+
05463 ;      | z <  -2816 (-$F500) <KM> |       0        | +62 <KM/H> | inbound        |
05464 ;      | z >= -2816 (-$F500) <KM> |      15        | -62 <KM/H> | outbound       |
05465 ;      +--------------------------+----------------+------------+----------------+
05466 ;
05467 ;      In other words, the Zylon ship accelerates into negative z-direction
05468 ;      (outbound) up to a distance of -2816 (-$(0B00)) <KM>, then reverses its
05469 ;      course and returns back to our starship (inbound).
05470 ;
05471 ; (10) Change Zylon velocity index toward milestone velocity index.
05472 ;
05473 ;      Compare all 3 Zylon velocity indices of the game-controlled Zylon ship
05474 ;      with their corresponding milestone velocity indices. Increment or
05475 ;      decrement the former to better match the latter. Use the new Zylon
05476 ;      velocity indices to pick the current velocity values from Zylon velocity
05477 ;      table ZYLONVELTAB ($BF99). 
05478 ;
05479 ; (11) Launch a Zylon photon torpedo?
05480 ;
05481 ;      Prepare launching a Zylon photon torpedo if either of the following
05482 ;      conditions are met:
05483 ;
05484 ;      o   PLAYER2 is not used as a photon torpedo
05485 ;
05486 ;      o   The y-coordinate of the Zylon ship is in the range of -768..+767
05487 ;          (-$0300..+$2FF) <KM>. 
05488 ;
05489 ;      or if
05490 ;
05491 ;      o   The Zylon photon torpedo is not alive
05492 ;
05493 ;      o   The corresponding Zylon photon torpedo delay timer has reached a
05494 ;          value of 0
05495 ;
05496 ;      o   The y-coordinate of the Zylon ship is in the range of -768..+767
05497 ;          (-$0300..+$2FF) <KM>. 
05498 ;
05499 ;      At this point the z-velocity vector component of the Zylon photon torpedo
05500 ;      is preloaded with a value of -80 or +80 <KM/H> depending on the Zylon
05501 ;      ship being in front or behind of our starship, respectively. 
05502 ;
05503 ;      Launch a Zylon photon torpedo if both of the following conditions are
05504 ;      met:
05505 ;
05506 ;      o   The Zylon ship is in front or behind of our starship, with the
05507 ;          exception of a Zylon ship behind our starship in a NOVICE mission
05508 ;          (our starship will never be shot in the back in a NOVICE mission).
05509 ;
05510 ;      o   The z-coordinate of the Zylon ship (no matter if in front or behind
05511 ;          our starship) is closer than 8192 ($20**) <KM>.
05512 ;
05513 ;      Finally, the Zylon photon torpedo is launched with a lifetime of 62 game
05514 ;      loop iterations. Its position vector is copied from the launching Zylon
05515 ;      ship in subroutine COPYPOSVEC ($ACAF). In addition, the Zylon ship is
05516 ;      earmarked for the tracking computer.
05517
05518 L.CTRLDZYLON    = $6A                   ; Index of currently game-controlled Zylon ship.
05519                                         ; Used values are:
05520                                         ;   0 -> Control Zylon ship 0
05521                                         ;   1 -> Control Zylon ship 1
05522 NEG             = $80                   ; Negative sign bit for velocity vector component
05523
05524 MANEUVER        LDA WARPSTATE           ; Return if in starbase sector or hyperwarp engaged
05525                 ORA ISSTARBASESECT      ;
05526                 BNE SKIP078             ;
05527
05528 ;*** Update x and y velocity of both our starship's photon torpedoes 0 and 1 ***
05529                 LDA ISTRACKING          ; Skip this if ship's torpedoes not tracking a target
05530                 BEQ SKIP080             ;
05531
05532                 LDX PLTRACKED           ; Load PLAYER index of tracked target space object
05533
05534                 SEC                     ; Prep A := PLAYER row number of target...
05535                 LDA PL0ROWNEW,X         ; ...- PLAYER row number photon torpedo 0
05536                 SBC PL3ROWNEW           ;
05537                 BCC SKIP079             ; Skip if target above our starship's photon torpedo
05538                 LDA #0                  ; Prep A := 0
05539 SKIP079         JSR HOMINGVEL           ; Get y-velocity for homing photon torpedo 0 and 1
05540                 STA PL3YVEL             ; Store y-velocity photon torpedo 0
05541                 STA PL4YVEL             ; Store y-velocity photon torpedo 1
05542
05543                 SEC                     ; Prep A := PLAYER column number of target...
05544                 LDA PL3COLUMN           ; ...- PLAYER column number of photon torpedo 0
05545                 SBC PL0COLUMN,X         ;
05546                 JSR HOMINGVEL           ; Get x-velocity for homing photon torpedo 0
05547                 STA PL3XVEL             ; Store x-velocity of photon torpedo 0
05548
05549                 SEC                     ; Prep A := PLAYER column number of target...
05550                 LDA PL4COLUMN           ; ...- PLAYER column number of photon torpedo 1
05551                 SBC PL0COLUMN,X         ;
05552                 JSR HOMINGVEL           ; Get x-velocity for homing photon torpedo 1
05553                 STA PL4XVEL             ; Store x-velocity of photon torpedo 1
05554
05555 ;*** Make Zylon ships follow rotation of our starship **************************
05556 SKIP080         LDX #3                  ; Loop over x and y velocity indices of both Zylons
05557 LOOP036         DEC ZYLONTIMX0,X        ; Decrement Zylon timer
05558                 BPL SKIP085             ; Next timer if this one still counting down
05559
05560                 TXA                     ; Prep joystick (x or y) value in -1, 0, +1
05561                 LSR A                   ;
05562                 TAY                     ;
05563                 LDA JOYSTICKX,Y         ;
05564
05565                 LDY SHIPVIEW            ; Skip if in Front view
05566                 BEQ SKIP081             ;
05567
05568                 EOR #$FF                ; Invert joystick value (when in Aft view)
05569                 CLC                     ; (two's-complement)
05570                 ADC #1                  ;
05571
05572 SKIP081         CLC                     ; Add joystick value to Zylon velocity index
05573                 ADC ZYLONVELINDX0,X     ;
05574                 BPL SKIP082             ;
05575                 LDA #0                  ;
05576 SKIP082         CMP #16                 ; Limit new Zylon velocity index to 0..15 ...
05577                 BCC SKIP083             ;
05578                 LDA #15                 ;
05579 SKIP083         STA ZYLONVELINDX0,X     ; ...and store new Zylon velocity index
05580
05581                 CMP #8                  ; Calc new Zylon timer value in 0, 2, ..., 14
05582                 BCC SKIP084             ;
05583                 EOR #$0F                ;
05584 SKIP084         ASL A                   ;
05585                 STA ZYLONTIMX0,X        ; ...and store new Zylon timer value
05586
05587 SKIP085         DEX                     ;
05588                 BPL LOOP036             ; Next Zylon timer
05589
05590 ;*** Update x and y velocity of single Zylon photon torpedo ********************
05591                 LDA PL2SHAPTYPE         ; Skip if PLAYER2 not PHOTON TORPEDO (shape type 0)
05592                 BNE SKIP088             ;
05593
05594                 LDY MISSIONLEVEL        ; Depending on mission level...
05595                 LDA ZYLONHOMVELTAB,Y    ; ...pick (initially negative) Zylon torpedo velocity
05596
05597                 LDX PL2YPOSHI           ; If photon torpedo in upper screen half (y >= 0)...
05598                 BPL SKIP086             ; ...don't toggle velocity sign -> torpedo goes down
05599                 AND #$7F                ; ...toggle velocity sign       -> torpedo goes up
05600 SKIP086         STA PL2YVEL             ; Store new y-velocity of Zylon photon torpedo
05601
05602                 ORA #NEG                ; Restore negative sign bit of velocity
05603
05604                 LDX PL2XPOSHI           ; If photon torpedo in right screen half (x >= 0)...
05605                 BPL SKIP087             ; ...don't toggle velocity sign -> torpedo goes left
05606                 AND #$7F                ; ...toggle velocity sign       -> torpedo goes right
05607 SKIP087         STA PL2XVEL             ; Store new x-velocity of Zylon photon torpedo
05608
05609 ;*** Create new meteor? ********************************************************
05610 SKIP088         LDA COUNT256            ; Attempt meteor creation in 7 out of 8 game loops
05611                 AND #$03                ;
05612                 BEQ SKIP092             ;
05613
05614 SKIP089         LDA PL2SHAPOFF          ; If PLAYER2 shape is initial try to create a meteor
05615                 BEQ SKIP090             ;
05616
05617                 LDA PL2LIFE             ; Return if PLAYER2 alive
05618                 BNE SKIP091             ;
05619
05620 SKIP090         LDA RANDOM              ; Return in 98% (252:256) (do not create meteor)
05621                 CMP #4                  ;
05622                 BCS SKIP091             ;
05623
05624 ;*** Create new meteor! ********************************************************
05625                 LDA #SHAP.METEOR        ; PLAYER2 is METEOR (shape type 6)
05626                 STA PL2SHAPTYPE         ;
05627                 LDX #2                  ; Randomize position vector of meteor
05628                 JSR INITPOSVEC          ;
05629                 LDA #60                 ; Meteor lifetime := 60 game loops
05630                 STA PL2LIFE             ;
05631                 LDA #NEG!8              ; SUMMARY:
05632                 STA PL2ZVEL             ; x-velocity :=  0 <KM/H>
05633                 LDA #0                  ; y-velocity :=  0 <KM/H>
05634                 STA PL2COLUMN           ; z-velocity := -8 <KM/H>
05635                 STA PL2XVEL             ;
05636                 STA PL2YVEL             ; PLAYER2 column number := 0 (offscreen)
05637 SKIP091         RTS                     ; Return
05638
05639 ;*** Toggle Zylon ship control *************************************************
05640 SKIP092         LDA CTRLDZYLON          ; Toggle control to the other Zylon ship
05641                 EOR #$01                ;
05642                 STA CTRLDZYLON          ;
05643
05644 ;*** Create a new Zylon ship? **************************************************
05645                 TAX                     ; Save index of controlled Zylon ship
05646                 LDA PL0LIFE,X           ; Skip creating Zylon ship if its PLAYER still alive
05647                 BNE SKIP094             ;
05648
05649                 LDA PL0LIFE             ; If both Zylon ships are not alive...
05650                 ORA PL1LIFE             ;
05651                 AND #$01                ;
05652                 LDY CURRSECTOR          ; ...and this an empty sector...
05653                 CMP GCMEMMAP,Y          ;
05654                 BCS SKIP089             ; ...attempt to create meteor and return
05655
05656 ;*** Create a new Zylon ship! **************************************************
05657                 LDA #255                ; Zylon ship lifetime := 255 game loops (infinite)
05658                 STA PL0LIFE,X           ;
05659
05660                 LDA RANDOM              ; Pick a Zylon ship shape type (1 out of 8)
05661                 AND #$07                ;
05662                 TAY                     ;
05663                 LDA ZYLONSHAPTAB,Y      ;
05664                 STA PL0SHAPTYPE,X       ;
05665
05666                 LDA MISSIONLEVEL        ; Init Zylon's flight pattern (0 if NOVICE mission)
05667                 BEQ SKIP093             ;
05668                 LDA ZYLONFLPATTAB,Y     ;
05669 SKIP093         STA ZYLONFLPAT0,X       ;
05670
05671                 LDA #1                  ; Zylon ship's milestone timer := 1 game loop
05672                 STA MILESTTIM0,X        ;
05673
05674                 STA ZPOSSIGN,X          ; Put Zylon ship in front of our starship
05675                 LDA RANDOM              ;
05676                 AND VICINITYMASK        ; y-coordinate (high byte) := RND(0..VICINITYMASK)
05677                 STA YPOSHI,X            ;
05678                 ADC #19                 ; x-coordinate (high byte) := y (high byte) + 19
05679                 STA XPOSHI,X            ;
05680                 ORA #$71                ; z-coordinate (high byte) := >= +28928 (+$71**) <KM>
05681                 STA ZPOSHI,X            ;
05682                 JSR RNDINVXY            ; Randomly invert x and y coordinate of pos vector
05683
05684 ;*** Set current flight pattern to attack flight pattern? **********************
05685 SKIP094         LDA ZPOSHI,X            ; Skip if Zylon too distant (z >= +$20** <KM>)
05686                 CMP #$20                ;
05687                 BCS SKIP096             ;
05688
05689                 LDA ZPOSSIGN,X          ; Set attack flight pattern if Zylon is behind
05690                 BEQ SKIP095             ;
05691
05692                 LDA PL0SHAPOFF,X        ; Skip if Zylon shape initial
05693                 BEQ SKIP096             ;
05694
05695                 CMP #$29                ; Skip if Zylon shape is Long-Range Scan blip
05696                 BEQ SKIP096             ;
05697
05698 SKIP095         LDA #0                  ; Set attack flight pattern
05699                 STA ZYLONFLPAT0,X       ;
05700
05701 ;*** Update back-attack flag and milestone velocity indices ********************
05702 SKIP096         DEC MILESTTIM0,X        ; Skip if milestone timer still counting down
05703                 BPL SKIP099             ;
05704
05705                 LDA #120                ; Milestone timer := 120 game loops
05706                 STA MILESTTIM0,X        ;
05707
05708                 LDA MISSIONLEVEL        ; Back-attack flag := 1 in 19% (48:256) of...
05709                 LDY RANDOM              ; ...WARRIOR or COMMANDER missions
05710                 CPY #48                 ; ...              := 0 otherwise
05711                 BCC SKIP097             ;
05712                 LSR A                   ;
05713 SKIP097         LSR A                   ;
05714                 STA ISBACKATTACK0,X     ;
05715
05716                                         ; Loop over all 3 milestone velocity indices
05717                 LDA ZYLONFLPAT0,X       ; Set new milestone velocity index:
05718 LOOP037         BIT RANDOM              ; If Zylon flight pattern is...
05719                 BPL SKIP098             ; ...0 -> milestone velocity index := either 0 or 15
05720                 EOR #$0F                ; ...1 -> milestone velocity index := either 1 or 14
05721 SKIP098         STA MILESTVELINDZ0,X    ; ...4 -> milestone velocity index := either 4 or 11
05722                 INX                     ;
05723                 INX                     ;
05724                 CPX #6                  ;
05725                 BCC LOOP037             ; Next Zylon milestone velocity index
05726
05727 ;*** Update milestone velocity indices in attack flight pattern ****************
05728                 LDX CTRLDZYLON          ; Reload index of controlled Zylon ship
05729
05730 SKIP099         LDA ZYLONFLPAT0,X       ; Skip if not in attack flight pattern
05731                 BNE SKIP105             ;
05732
05733                 LDY CTRLDZYLON          ; Reload index of controlled Zylon ship
05734
05735                                         ; Loop over all 3 milestone velocity indices
05736 LOOP038         CPY #$31                ; Skip to handle x and y velocity index
05737                 BCS SKIP101             ;
05738                                         ; SUMMARY:
05739                 LDA ISBACKATTACK0,Y     ; Handle z-velocity index:
05740                 LSR A                   ;
05741                 LDA ZPOSHI,Y            ; If Zylon attacks from front...
05742                 BCS SKIP100             ; z <  $0A00 <KM> -> mil vel index := 0  (+62 <KM/H>)
05743                 CMP #$0A                ; z >= $0A00 <KM> -> mil vel index := 15 (-62 <KM/H>)
05744                 BCC SKIP103             ;
05745                 BCS SKIP101             ; If Zylon attacks from back...
05746 SKIP100         CMP #$F5                ; z >= $F500 <KM> -> mil vel index := 15 (-62 <KM/H>)
05747                 BCS SKIP102             ; z <  $F500 <KM> -> mil vel index := 0  (+62 <KM/H>)
05748
05749 SKIP101         LDA ZPOSSIGN,Y          ; Handle x and y velocity index:
05750                 LSR A                   ;
05751 SKIP102         LDA #15                 ; x >= 0 <KM> -> mil vel index := 15 (-62 <KM/H>)
05752                 BCS SKIP104             ; x <  0 <KM> -> mil vel index := 0  (+62 <KM/H>)
05753 SKIP103         LDA #0                  ; y >= 0 <KM> -> mil vel index := 15 (-62 <KM/H>)
05754 SKIP104         STA MILESTVELINDZ0,X    ; y <  0 <KM> -> mil vel index := 0  (+62 <KM/H>)
05755
05756                 CLC                     ; Adjust position vector component index
05757                 TYA                     ;
05758                 ADC #NUMSPCOBJ.ALL      ;
05759                 TAY                     ;
05760
05761                 INX                     ;
05762                 INX                     ;
05763                 CPX #6                  ;
05764                 BCC LOOP038             ; Next milestone velocity index
05765
05766 ;*** Acceleration: Change Zylon velocity index toward milestone velocity index *
05767                 LDX CTRLDZYLON          ; Reload index of controlled Zylon ship
05768 SKIP105         LDY CTRLDZYLON          ; Reload index of controlled Zylon ship
05769
05770                                         ; Loop over all 3 milestone velocity indices
05771 LOOP039         LDA ZYLONVELINDZ0,X     ; Compare Zylon velocity index with milestone index
05772                 CMP MILESTVELINDZ0,X    ;
05773                 BEQ SKIP107             ; Skip if equal
05774                 BCS SKIP106             ;
05775                 INC ZYLONVELINDZ0,X     ; Increm. Zylon velocity index if < milestone index
05776                 BCC SKIP107             ;
05777 SKIP106         DEC ZYLONVELINDZ0,X     ; Decrem. Zylon velocity index if >= milestone index
05778
05779 SKIP107         STX L.CTRLDZYLON        ; Save index of controlled Zylon ship
05780                 TAX                     ;
05781                 LDA ZYLONVELTAB,X       ; Pick new velocity value by Zylon velocity index
05782                 LDX L.CTRLDZYLON        ; Reload index of controlled Zylon ship
05783                 STA ZVEL,Y              ; Store new velocity vector component of Zylon ship
05784
05785                 TYA                     ; Next velocity vector component
05786                 CLC                     ;
05787                 ADC #NUMSPCOBJ.ALL      ;
05788                 TAY                     ;
05789
05790                 INX                     ;
05791                 INX                     ;
05792                 CPX #6                  ;
05793                 BCC LOOP039             ; Next milestone velocity index
05794
05795 ;*** Launch Zylon photon torpedo? **********************************************
05796
05797 ;*** Check PLAYER2 shape and lifetime ******************************************
05798                 LDX CTRLDZYLON          ; Reload index of controlled Zylon ship
05799
05800                 LDA PL2SHAPTYPE         ; Skip if PLAYER2 not PHOTON TORPEDO (shape type 0)
05801                 BNE SKIP109             ;
05802
05803                 LDA PL2LIFE             ; Return if Zylon photon torpedo still alive
05804                 BNE SKIP108             ;
05805
05806                 LDA TORPEDODELAY        ; Count down Zylon photon torpedo delay timer...
05807                 BEQ SKIP109             ; ...before launching next Zylon photon torpedo
05808                 DEC TORPEDODELAY        ;
05809 SKIP108         RTS                     ; Return
05810
05811 ;*** Check y-coordinate of Zylon ship ******************************************
05812 SKIP109         CLC                     ; Return if Zylon ship's y-coordinate not...
05813                 LDA YPOSHI,X            ; ...in -768..+767 (-$(0300)..+$2FF) <KM>.
05814                 ADC #2                  ;
05815                 CMP #5                  ;
05816                 BCS SKIP108             ;
05817
05818 ;*** Set Zylon photon torpedo's z-velocity *************************************
05819                 LDY #NEG!80             ; Prep Zylon torpedo's z-velocity := -80 <KM/H>
05820
05821                 LDA ZPOSSIGN,X          ; Prep Zylon ship's sign of z-coordinate
05822                 LSR A                   ;
05823                 LDA ZPOSHI,X            ; Prep Zylon ship's z-coordinate
05824                 BCS SKIP110             ; Skip if Zylon ship in front...
05825                 EOR #$FF                ; ...else invert loaded Zylon ship's z-coordinate
05826
05827                 LDY MISSIONLEVEL        ; Return (no torpedo from back) if NOVICE mission
05828                 BEQ SKIP108             ;
05829
05830                 LDY #80                 ; Preload Zylon torpedo's z-velocity := +80 <KM/H>
05831
05832 ;*** Is Zylon ship in range? ***************************************************
05833 SKIP110         CMP #$20                ; Return if Zylon ship too far...
05834                 BCS SKIP108             ; ... (ABS(z-coordinate) > 8192 ($20**) <KM>)
05835
05836                 STY PL2ZVEL             ; Store Zylon photon torpedo's z-velocity
05837
05838 ;*** Launch Zylon photon torpedo! **********************************************
05839
05840                 LDA #0                  ; PLAYER2 is PHOTON TORPEDO (shape type 0)
05841                 STA PL2SHAPTYPE         ;
05842                 STA PL2COLUMN           ; Zylon torpedo PLAYER column number := 0 (offscreen)
05843                 LDA #62                 ;
05844                 STA PL2LIFE             ; Zylon torpedo lifetime := 62 game loops
05845
05846                 LDX #2                  ; Prep source index for position vector copy
05847                 LDY CTRLDZYLON          ; Prep destination index for position vector copy
05848                 STY ZYLONATTACKER       ; Save Zylon ship index for tracking computer
05849                 JMP COPYPOSVEC          ; Copy position vector from Zylon ship to its torpedo
05850
05851 ;*******************************************************************************
05852 ;*                                                                             *
05853 ;*                                  INITEXPL                                   *
05854 ;*                                                                             *
05855 ;*                            Initialize explosion                             *
05856 ;*                                                                             *
05857 ;*******************************************************************************
05858
05859 ; DESCRIPTION
05860 ;
05861 ; Initializes the explosion's lifetime, the explosion fragments' position and
05862 ; velocity vectors as well as their pixel row and column numbers.
05863 ;
05864 ; An explosion has a lifetime of 128 game loop iterations. It consists of 32
05865 ; explosion fragment space objects with indices 17..48. The position vector of
05866 ; each explosion fragment is copied from the exploding PLAYER space object.
05867 ;
05868 ; The pixel column number of each explosion fragment is initialized to
05869 ;
05870 ;     PIXEL COLUMN NUMBER := PLAYER column number - 48 + RND(0..15)
05871 ;
05872 ; To convert PLAYER column numbers (in Player/Missile (PM) pixels) into pixel
05873 ; column numbers, the PLAYER column number of the left PLAYFIELD border (= 48)
05874 ; is subtracted and a random number is added.
05875 ;
05876 ; BUG (at $AC76): The added random number should not be in 0..15 but in 0..7
05877 ; because the exploding PLAYER is 8 pixels wide. The PLAYER column number
05878 ; represents the left edge of the PLAYER shape. When using a random number in
05879 ; 0..15, half of the pixels are located off to the right of the PLAYER, outside
05880 ; the PLAYER area. Suggested fix: Replace instruction AND #$0F with AND #$07. 
05881 ;
05882 ; The pixel row number of each explosion fragment is initialized to
05883 ;
05884 ;     PIXEL ROW NUMBER := (PLAYER row number - RND(0..15)) / 2 - 16
05885 ;
05886 ; BUG (at $AC88): To convert PLAYER row numbers (in PM pixels) into pixel row
05887 ; numbers, the PLAYER row number to the top PLAYFIELD border (= 16) should be
05888 ; subtracted first, then the division by 2 (instruction LRS A) should be applied
05889 ; to reduce the double-line PM resolution to the single-line PLAYFIELD
05890 ; resolution. Suggested fix: Swap instruction LRS A with SBC #16 which leads to
05891 ; the following formula for the pixel row number:
05892 ;
05893 ;     PIXEL ROW NUMBER := (PLAYER row number - 16 + RND(0..15)) / 2
05894 ;
05895 ; Incidentally, adding a random number in 0..15 is correct. PLAYER row number
05896 ; represents the top edge of the PLAYER shape, which is typically 16 PM pixels
05897 ; tall when representing a close space object.
05898 ;
05899 ; The velocity vector of explosion fragments is set to random x, y, and z
05900 ; velocity vector components in -7..+7 <KM/H>.
05901 ;
05902 ; INPUT
05903 ;
05904 ;   Y = PLAYER index from which the explosion originates. Used values are:
05905 ;     0 -> Explosion of PLAYER0 (Zylon ship 0)
05906 ;     1 -> Explosion of PLAYER1 (Zylon ship 1)
05907 ;     2 -> Explosion of PLAYER2 (Zylon photon torpedo, starbase, or meteor)
05908
05909 INITEXPL        LDA #128                ; Explosion lifetime := 128 game loops
05910                 STA EXPLLIFE            ;
05911
05912                 LDX #NUMSPCOBJ.ALL-1    ; Max index of space objects (for explosion frags)
05913                 STX MAXSPCOBJIND        ;
05914
05915                                         ; Loop over all explosion fragment position vectors
05916                                         ; (index 48..17)
05917 LOOP040         LDA RANDOM              ; PIXEL COLUMN NUM := PLAYER column - 48 + RND(0..15)
05918                 AND #$0F                ; (!)
05919                 ADC PL0COLUMN,Y         ;
05920                 SBC #48                 ;
05921                 STA PIXELCOLUMN,X       ;
05922
05923                 LDA RANDOM              ; PIXEL ROW NUM := (PLAYER row + RND(0..15)) / 2 - 16
05924                 AND #$0F                ;
05925                 ADC PL0ROWNEW,Y         ;
05926                 LSR A                   ; (!)
05927                 SBC #16                 ;
05928                 STA PIXELROWNEW,X       ;
05929
05930                 JSR COPYPOSVEC          ; Copy position vector of PLAYER to explosion frag
05931
05932                 LDA RANDOM              ; z-velocity := RND(-7..+7) <KM/H>
05933                 AND #NEG!7              ;
05934                 STA ZVEL,X              ;
05935                 LDA RANDOM              ; x-velocity := RND(-7..+7) <KM/H>
05936                 AND #NEG!7              ;
05937                 STA XVEL,X              ;
05938                 LDA RANDOM              ; y-velocity := RND(-7..+7) <KM/H>
05939                 AND #NEG!7              ;
05940                 STA YVEL,X              ;
05941
05942                 DEX                     ; Next explosion fragment position vector
05943                 CPX #16                 ;
05944                 BNE LOOP040             ;
05945                 RTS                     ; Return
05946
05947 ;*******************************************************************************
05948 ;*                                                                             *
05949 ;*                                 COPYPOSVEC                                  *
05950 ;*                                                                             *
05951 ;*                           Copy a position vector                            *
05952 ;*                                                                             *
05953 ;*******************************************************************************
05954
05955 ; DESCRIPTION
05956 ;
05957 ; Copies a position vector.
05958 ;
05959 ; Actually, this subroutine copies the z-coordinate only, then code execution
05960 ; continues into subroutine COPYPOSXY ($ACC1) to copy the x and y coordinate.
05961 ;
05962 ; INPUT
05963 ;
05964 ;   X = Destination position vector index. Used values are: 0..48.
05965 ;   Y = Source position vector index. Used values are: 0..48.
05966
05967 COPYPOSVEC      LDA ZPOSSIGN,Y          ;
05968                 STA ZPOSSIGN,X          ;
05969                 LDA ZPOSHI,Y            ;
05970                 STA ZPOSHI,X            ;
05971                 LDA ZPOSLO,Y            ;
05972                 STA ZPOSLO,X            ;
05973
05974 ;*******************************************************************************
05975 ;*                                                                             *
05976 ;*                                  COPYPOSXY                                  *
05977 ;*                                                                             *
05978 ;*          Copy x and y components (coordinates) of position vector           *
05979 ;*                                                                             *
05980 ;*******************************************************************************
05981
05982 ; DESCRIPTION
05983 ;
05984 ; Copies the x and y components (coordinates) of a position vector.
05985 ;
05986 ; INPUT
05987 ;
05988 ;   X = Destination position vector index. Used values are: 0..48.
05989 ;   Y = Source position vector index. Used values are: 0..48.
05990
05991 COPYPOSXY       LDA XPOSSIGN,Y          ;
05992                 STA XPOSSIGN,X          ;
05993                 LDA XPOSHI,Y            ;
05994                 STA XPOSHI,X            ;
05995                 LDA YPOSSIGN,Y          ;
05996                 STA YPOSSIGN,X          ;
05997                 LDA YPOSHI,Y            ;
05998                 STA YPOSHI,X            ;
05999                 LDA XPOSLO,Y            ;
06000                 STA XPOSLO,X            ;
06001                 LDA YPOSLO,Y            ;
06002                 STA YPOSLO,X            ;
06003 SKIP111         RTS                     ; Return
06004
06005 ;*******************************************************************************
06006 ;*                                                                             *
06007 ;*                                   DOCKING                                   *
06008 ;*                                                                             *
06009 ;*      Handle docking at starbase, launch and return of transfer vessel       *
06010 ;*                                                                             *
06011 ;*******************************************************************************
06012
06013 ; DESCRIPTION
06014 ;
06015 ; Handles docking at a starbase, launching and returning the transfer vessel,
06016 ; and repairing our starship's subsystems. 
06017 ;
06018 ; This subroutine changes, if in Front view, the PLAYER-PLAYFIELD priority such
06019 ; that PLAYERs like the starbase appear behind the cross hairs, which are part
06020 ; of the PLAYFIELD.
06021 ;
06022 ; BUG (at $ACEE): In Front view, the specific order of PLAYERs (PL0..4) and
06023 ; PLAYFIELD colors (PF0..4) is, from front to back:
06024 ;
06025 ;     PL4 > PF0, PF1, PF2 > PL0 > PL1 > PL2 > PL3 > PF4 (BGR)
06026 ;
06027 ; This makes the starbase appear behind the cross hairs, but also behind the
06028 ; stars, as both cross hairs and stars are part of the PLAYFIELD - a rarely
06029 ; noticed glitch.
06030 ;
06031 ; Note also that, as an exception of the rule, PLAYER4 (transfer vessel) is
06032 ; displayed before the PLAYFIELD. Thus, the transfer vessel appears in front of
06033 ; the cross hairs!
06034 ;
06035 ; In Aft view, the arrangement is reversed: PLAYERs are arranged in front of the
06036 ; PLAYFIELD. The specific order of PLAYERs (PL0..4) and PLAYFIELD colors
06037 ; (PF0..4) is, from front to back:
06038 ;
06039 ;     PL0 > PL1 > PL2 > PL3 > PL4 > PF0, PF1, PF2 > PF4 (BGR)
06040 ;
06041 ; In this case, both the starbase and the transfer vessel appear in front of the
06042 ; cross hairs! Suggested fix: None, technically not possible.
06043 ;
06044 ;
06045 ; The starbase is tracked and the PLAYER0..2 shape types are set to STARBASE
06046 ; RIGHT, STARBASE LEFT, and STARBASE CENTER, respectively, combining them into a
06047 ; 3-part starbase shape. 
06048 ;
06049 ; If this sector is still marked as a starbase sector but no more so on the
06050 ; Galactic Chart (if in the meantime either Zylon units have surrounded this
06051 ; sector and destroyed the starbase or you have destroyed the starbase with a
06052 ; photon torpedo) then the noise sound pattern SHIELD EXPLOSION is played in
06053 ; subroutine NOISE ($AEA8) and code execution returns.
06054 ;
06055 ; Otherwise a minimum distance to the starbase of +32 (+$0020) <KM> is enforced
06056 ; and the conditions for a successful docking are checked:
06057 ;
06058 ; DOCKING CONDITIONS
06059 ;
06060 ; A docking is successful if all of the following conditions are met:
06061 ;
06062 ; (1)  The PLAYER2 (STARBASE CENTER) column number is in 120..135. 
06063 ;
06064 ;      BUG (at $AD39): At first glance, the PLAYER column interval of 120..135
06065 ;      corresponds to an almost symmetric interval of -8..+7 PM pixels relative
06066 ;      to the horizontal center of the PLAYFIELD, at PLAYER column number 128
06067 ;      (48 PM pixels offset to left PLAYFIELD border + 80 PM pixels to the
06068 ;      PLAYFIELD center). This is correct only if the PLAYER column number were
06069 ;      to designate the horizontal center of the PLAYER. However it designates
06070 ;      its left edge! Thus the used pixel column number range 120..135 creates
06071 ;      an asymmetric horizontal docking position: A docking is successful if the
06072 ;      horizontal position of the starbase shape's center is roughly -5..+10 PM
06073 ;      pixels relative to the horizontal center of the PLAYFIELD. Suggested fix:
06074 ;      Replace SBC #120 with SBC #117. This leads to an interval of -8..+7
06075 ;      pixels relative to the horizontal center of the PLAYFIELD and better
06076 ;      symmetry in the horizontal docking position.
06077 ;
06078 ; (2)  The PLAYER2 (STARBASE CENTER) row number is in 104..119.
06079 ;
06080 ;      BUG (at $AD43): The PLAYER row interval of 104..119 corresponds to an
06081 ;      asymmetric interval of -20..-5 PM pixels relative to the vertical center
06082 ;      of the PLAYFIELD, at pixel row number 80 or PLAYER row number 124. It
06083 ;      lets you dock at a starbase that "sits" on top of the horizontal cross
06084 ;      hairs but not at one that "hangs" from them. Suggested fix: Replace SBC
06085 ;      #104 with SBC #108. This leads to an interval of -8..+7 pixels relative
06086 ;      to the vertical center of the PLAYFIELD (assuming a PLAYER2 shape of 16
06087 ;      pixel height, which is typical during docking) and better symmetry in the
06088 ;      vertical docking position. 
06089 ;
06090 ; (3)  The starbase is in correct distance in front of our starship: The
06091 ;      starbase's z-coordinate must be < +512 (+$02**) <KM>.
06092 ;
06093 ; (4)  Our starship is horizontally level with the starbase: The starbase's
06094 ;      y-coordinate must be < +256 (+$01**) <KM>.
06095 ;
06096 ; (5)  Our starship is at a complete halt.
06097 ;
06098 ; DOCKING SUCCESSFUL
06099 ;
06100 ; If the conditions for a successful docking are met, the subsequent docking and
06101 ; transfer operation can be divided in the following states, starting with state
06102 ; NOT DOCKED:
06103 ;
06104 ; (1)  NOT DOCKED 
06105 ;
06106 ;      The docking state is set to ORBIT ESTABLISHED and the title line is
06107 ;      updated with "ORBIT ESTABLISHED".
06108 ;
06109 ; (2)  ORBIT ESTABLISHED 
06110 ;
06111 ;      After waiting until the title line "ORBIT ESTABLISHED" has disappeared,
06112 ;      the transfer vessel is initialized and launched: The PLAYER4 shape type
06113 ;      is set to TRANSFER VESSEL. Its position vector is set to a position above
06114 ;      and in front of our starship, but behind the starbase:
06115 ;
06116 ;          x-coordinate :=     +0..+255 (+$00**) <KM>
06117 ;          y-coordinate :=   +256..+511 (+$01**) <KM> 
06118 ;          z-coordinate := +4096..+4351 (+$10**) <KM>
06119 ;
06120 ;      Its velocity vector is set to
06121 ;
06122 ;          x-velocity   := +1 <KM/H> 
06123 ;          y-velocity   := -1 <KM/H> 
06124 ;          z-velocity   := -7 <KM/H>
06125 ;
06126 ;      This will move the transfer vessel from behind the starbase into a
06127 ;      direction toward and a little to the lower right of our starship. The
06128 ;      lifetime of the transfer vessel (and its return journey) is set to 129
06129 ;      game loop iterations. Finally, the docking state is set to RETURN
06130 ;      TRANSFER VESSEL.
06131 ;
06132 ; (3)  RETURN TRANSFER VESSEL 
06133 ;
06134 ;      After checking if the transfer vessel has passed behind our starship, the
06135 ;      beeper sound pattern ACKNOWLEDGE is played in subroutine BEEP ($B3A6),
06136 ;      the title line is updated with "TRANSFER COMPLETE", our starship's
06137 ;      subsystems are repaired, and our starship's ENERGY readout is restored to
06138 ;      9999 energy units. by inverting the z-velocity the velocity vector of the
06139 ;      transfer vessel is changed to
06140 ;
06141 ;          x-velocity   := +1 <KM/H> 
06142 ;          y-velocity   := -1 <KM/H> 
06143 ;          z-velocity   := +7 <KM/H>
06144 ;
06145 ;      thus launching the transfer vessel on its return journey to the starbase.
06146 ;      The docking state is set to TRANSFER COMPLETE. Finally, the screen is
06147 ;      updated in subroutine UPDSCREEN ($B07B).
06148 ;
06149 ; (4)  TRANSFER COMPLETE 
06150 ;
06151 ;      This docking state marks the end of a successful docking and transfer
06152 ;      operation.
06153 ;
06154 ; DOCKING ABORTED
06155 ;
06156 ; If the docking conditions above are not met and the docking state is already
06157 ; ORBIT ESTABLISHED or RETURN TRANSFER VESSEL then the message "DOCKING ABORTED"
06158 ; is displayed and the docking state is set to NOT DOCKED.
06159
06160 DOCKING         LDA ISSTARBASESECT      ; Return if not in starbase sector
06161                 BEQ SKIP111             ;
06162
06163                 LDA SHIPVIEW            ; Skip if not in Front view
06164                 BNE SKIP112             ;
06165                 LDA #$14                ; GTIA: Enable PLAYER4, prio: PFs > PLs > BGR (!)
06166                 STA PRIOR               ; (Cross hairs in front of PLAYERs)
06167
06168 SKIP112         LDA #2                  ; Track starbase (PLAYER2)
06169                 STA TRACKDIGIT          ;
06170
06171 ;** Initialize starbase shape **************************************************
06172                 LDA #SHAP.STARBASEC     ; PLAYER2 is STARBASE CENTER (shape type 3)
06173                 STA PL2SHAPTYPE         ;
06174                 LDA #SHAP.STARBASEL     ; PLAYER1 is STARBASE LEFT (shape type 2)
06175                 STA PL1SHAPTYPE         ;
06176                 LDA #SHAP.STARBASER     ; PLAYER0 is STARBASE RIGHT (shape type 4)
06177                 STA PL0SHAPTYPE         ;
06178
06179                 LDA #255                ; Prep starbase lifetime := 255 game loops (infinite)
06180
06181                 LDX CURRSECTOR          ; Skip if starbase in current sector
06182                 LDY GCMEMMAP,X          ;
06183                 BMI SKIP113             ;
06184
06185                 LDA #0                  ; Prep starbase lifetime := 0 game loops (fast death)
06186
06187 SKIP113         STA PL0LIFE             ; PLAYER0 lifetime := either 0 or 255 game loops
06188                 STA PL1LIFE             ; PLAYER1 lifetime := either 0 or 255 game loops
06189                 STA PL2LIFE             ; PLAYER2 lifetime := either 0 or 255 game loops
06190                 STA ISSTARBASESECT      ; Store starbase-in-sector flag
06191                 BMI SKIP114             ; Skip if starbase in current sector
06192
06193                 LDY #2                  ; Init explosion at PLAYER2 (STARBASE CENTER)
06194                 JSR INITEXPL            ;
06195
06196                 LDX #$0A                ; Play noise sound pattern SHIELD EXPLOSION, return
06197                 JMP NOISE               ;
06198
06199 ;*** Keep minimum distance to starbase *****************************************
06200 SKIP114         LDA PL2ZPOSHI           ; Skip if starbase z-coordinate > +255 (+$00**) <KM>
06201                 BNE SKIP115             ;
06202
06203                 LDA PL2ZPOSLO           ; Approach starbase not closer than +32 (+$0020) <KM>
06204                 CMP #32                 ;
06205                 BCS SKIP115             ;
06206                 INC PL2ZPOSLO           ; ...else push starbase back
06207
06208 ;*** Check if in docking range *************************************************
06209 SKIP115         LDA PL2COLUMN           ; Abort docking if PLAYER column number of...
06210                 SEC                     ; ...PLAYER2 (STARBASE CENTER) not in 120..135.
06211                 SBC #120                ; (!)
06212                 CMP #16                 ;
06213                 BCS SKIP116             ;
06214
06215                 LDA PL2ROWNEW           ; Abort docking if PLAYER row number of...
06216                 SEC                     ; ...PLAYER2 (STARBASE CENTER) not in 104..119.
06217                 SBC #104                ; (!)
06218                 CMP #16                 ;
06219                 BCS SKIP116             ;
06220
06221                 LDA PL2ZPOSHI           ; Abort docking if...
06222                 CMP #2                  ; ... z-coordinate of starbase >= +512 (+$02**) <KM>
06223                 BCS SKIP116             ;
06224
06225                 LDA PL2ZPOSSIGN         ; Abort docking...
06226                 AND PL2YPOSSIGN         ; ...if starbase not in front and upper screen half
06227                 EOR #$01                ;
06228                 ORA VELOCITYLO          ; ...if our starship's velocity not zero
06229                 ORA PL2YPOSHI           ; ...if starbase not roughly vertically centered
06230                 ORA NEWVELOCITY         ; ...if our starship's new velocity not zero
06231                 BEQ SKIP119             ; Else skip and handle docking
06232
06233 ;*** Docking aborted ***********************************************************
06234 SKIP116         LDA DOCKSTATE           ; Skip if DOCKSTATE is NOT DOCKED, TRANSFER COMPLETE
06235                 CMP #2                  ;
06236                 BCC SKIP117             ;
06237
06238                 LDY #$1F                ; Set title phrase "DOCKING ABORTED"
06239                 JSR SETTITLE            ;
06240
06241 SKIP117         LDA #0                  ; DOCKSTATE := NOT DOCKED
06242                 STA DOCKSTATE           ;
06243 SKIP118         RTS                     ; Return
06244
06245 ;*** Docking successful, check docking state ***********************************
06246 SKIP119         BIT DOCKSTATE           ; Check DOCKSTATE
06247                 BVS SKIP120             ; If DOCKSTATE = ORBIT ESTABLISHED hide title line
06248                 BMI SKIP122             ; If DOCKSTATE = RETURN TRANSFER VESSEL return it
06249                 LDA DOCKSTATE           ;
06250                 BNE SKIP118             ; Return if DOCKSTATE not NOT DOCKED
06251                 DEC DOCKSTATE           ; DOCKSTATE := ORBIT ESTABLISHED
06252
06253                 LDY #$1C                ; Set title phrase "ORBIT ESTABLISHED" and return
06254                 JMP SETTITLE            ;
06255
06256 ;*** Orbit established *********************************************************
06257 SKIP120         LDX #0                  ; Enqueue new, empty title phrase
06258                 STX NEWTITLEPHR         ;
06259
06260                 LDY TITLEPHR            ; Return if "ORBIT ESTABLISHED" still displayed
06261                 BNE SKIP118             ;
06262
06263 ;*** Launch transfer vessel ****************************************************
06264                 LDA #SHAP.TRANSVSSL     ; PLAYER4 is TRANSFER VESSEL (shape 5)
06265                 STA PL4SHAPTYPE         ;
06266
06267                 LDA #1                  ; Place transfer vessel behind starbase:
06268                 STA PL4ZPOSSIGN         ; x-coordinate :=    +0..+255  (+$00**) <KM>
06269                 STA PL4XPOSSIGN         ; y-coordinate :=  +256..+511  (+$01**) <KM>
06270                 STA PL4YPOSSIGN         ; z-coordinate := +4096..+4351 (+$10**) <KM>
06271                 STA PL4YPOSHI           ;
06272                 STA PL4XVEL             ; Move transfer vessel toward our starship:
06273                 LDA #$10                ; x-velocity := +1 <KM/H>
06274                 STA PL4ZPOSHI           ; y-velocity := -1 <KM/H>
06275                 LDA #$00                ; z-velocity := -7 <KM/H>
06276                 STA PL4XPOSHI           ;
06277                 LDA #NEG!7              ;
06278                 STA PL4ZVEL             ;
06279                 LDA #NEG!1              ; DOCKSTATE := RETURN TRANSFER VESSEL
06280                 STA DOCKSTATE           ;
06281                 STA PL4YVEL             ;
06282                 STA PL4LIFE             ; Transfer vessel lifetime := 129 game loops
06283 SKIP121         RTS                     ; Return
06284
06285 ;*** Return transfer vessel ****************************************************
06286 SKIP122         LDA PL4ZPOSSIGN         ; Return if transfer vessel in front of our starship
06287                 BNE SKIP121             ;
06288
06289                 LDX #$0C                ; Play beeper sound pattern ACKNOWLEGDE
06290                 JSR BEEP                ;
06291
06292                 LDY #$21                ; Set title phrase "TRANSFER COMPLETE"
06293                 JSR SETTITLE            ;
06294
06295                 LDX #5                  ; Repair all 6 subsystems
06296 LOOP041         LDA PANELTXTTAB+73,X    ;
06297                 STA GCSTATPHO,X         ;
06298                 DEX                     ;
06299                 BPL LOOP041             ;
06300
06301                 LDA #CCS.COL2!CCS.9     ; Set starship's ENERGY readout to "9999" in COLOR2
06302                 LDX #3                  ;
06303 LOOP042         STA ENERGYD1,X          ;
06304                 DEX                     ;
06305                 BPL LOOP042             ;
06306
06307                 LDA #7                  ; Move transfer vessel back toward starbase:
06308                 STA PL4ZVEL             ; x-velocity := -1 <KM/H>
06309                 LDA #NEG!1              ; y-velocity := +1 <KM/H>
06310                 STA PL4XVEL             ; z-velocity := +7 <KM/H>
06311                 LDA #1                  ;
06312                 STA PL4YVEL             ;
06313
06314                 STA DOCKSTATE           ; DOCKSTATE := TRANSFER COMPLETE
06315                 JMP UPDSCREEN           ; Update screen and return
06316
06317 ;*******************************************************************************
06318 ;*                                                                             *
06319 ;*                                   MODDLST                                   *
06320 ;*                                                                             *
06321 ;*                             Modify Display List                             *
06322 ;*                                                                             *
06323 ;*******************************************************************************
06324
06325 ; DESCRIPTION
06326 ;
06327 ; Modifies the Display List to show and hide title, headers, and the Control
06328 ; Panel Display.
06329 ;
06330 ; INPUT
06331 ;
06332 ;   A = Number of bytes to copy into the Display List
06333 ;   X = Offset into Display List DSPLST ($0280)
06334 ;   Y = Offset into Display List fragment table DLSTFRAG ($BA62). If Y = $80
06335 ;       then no bytes are copied but the specified locations of the Display List
06336 ;       are overwritten with Display List instruction $0D (one row of
06337 ;       GRAPHICS7).
06338 ;
06339 ;   Used values are:
06340 ;
06341 ;    A    X    Y
06342 ;   $08  $5F  $00 -> Show Control Panel Display (bottom text window)
06343 ;   $08  $5F  $80 -> Hide Control Panel Display (bottom text window)
06344 ;   $07  $0F  $23 -> Show title line
06345 ;   $07  $0F  $80 -> Hide title line
06346 ;   $08  $02  $1B -> Show Display List header line of Front view
06347 ;   $08  $02  $13 -> Show Display List header line of Aft view
06348 ;   $08  $02  $0B -> Show Display List header line of Long-Range Scan view
06349 ;   $08  $02  $08 -> Show Display List header line of Galactic Chart view
06350
06351 L.NUMBYTES      = $6A                   ; Number of bytes to copy
06352
06353 MODDLST         SEI                     ; Disable IRQ
06354                 STA L.NUMBYTES          ; Save number of bytes to copy
06355
06356 LOOP043         LDA VCOUNT              ; Wait for ANTIC line counter >= 124 (PLAYFIELD...
06357                 CMP #124                ; ...bottom) before changing the Display List
06358                 BCC LOOP043             ;
06359
06360 LOOP044         LDA DLSTFRAG,Y          ; Load byte from Display List fragment table
06361                 INY                     ;
06362                 BPL SKIP123             ; Skip if fragment table index < $80
06363                 LDA #$0D                ; Prep Display List instruction $0D (GRAPHICS7)
06364 SKIP123         STA DSPLST,X            ; Store byte in Display List
06365                 INX                     ;
06366                 DEC L.NUMBYTES          ;
06367                 BNE LOOP044             ; Copy next byte
06368
06369                 CLI                     ; Enable IRQ
06370                 RTS                     ; Return
06371
06372 ;*******************************************************************************
06373 ;*                                                                             *
06374 ;*                                CLRPLAYFIELD                                 *
06375 ;*                                                                             *
06376 ;*                           Clear PLAYFIELD memory                            *
06377 ;*                                                                             *
06378 ;*******************************************************************************
06379
06380 ; DESCRIPTION
06381 ;
06382 ; Clears PLAYFIELD memory from $1000 to $1FFF.
06383 ;
06384 ; This subroutine sets the start address of the memory to be cleared then code
06385 ; execution continues into subroutine CLRMEM ($AE0F) where the memory is
06386 ; actually cleared.
06387
06388 CLRPLAYFIELD    LDA #$10
06389
06390 ;*******************************************************************************
06391 ;*                                                                             *
06392 ;*                                   CLRMEM                                    *
06393 ;*                                                                             *
06394 ;*                                Clear memory                                 *
06395 ;*                                                                             *
06396 ;*******************************************************************************
06397
06398 ; DESCRIPTION
06399 ;
06400 ; Clears memory from a given start address to memory address $1FFF. This
06401 ; subroutine is called in the following situations:
06402 ;
06403 ; (1)  In routine INITCOLD ($A14A) at the beginning of the game to initialize
06404 ;      the game's variables 
06405 ;
06406 ; (2)  In subroutine CLRPLAYFIELD ($AE0D) to clear PLAYFIELD memory.
06407 ;
06408 ; As a side effect this subroutine also clears the saved number of space objects
06409 ; and the lock-on flag.
06410 ;
06411 ; INPUT
06412 ;
06413 ;   A = Start address (high byte) of memory to be cleared. Used values are:
06414 ;     $02 -> Clear memory $0200..$1FFF during game initialization
06415 ;     $10 -> Clear PLAYFIELD memory $1000..$1FFF
06416
06417 CLRMEM          STA MEMPTR+1            ; Store start address (high byte) to be cleared
06418                 LDA #0                  ; Store start address (low byte) to be cleared
06419                 TAY                     ;
06420                 STA MEMPTR              ;
06421
06422                 STA ISINLOCKON          ; Clear lock-on flag
06423                 STA OLDMAXSPCOBJIND     ; Clear saved number of space objects
06424
06425 LOOP045         STA (MEMPTR),Y          ; Clear memory location
06426                 INY                     ;
06427                 BNE LOOP045             ;
06428
06429                 INC MEMPTR+1            ; Next page (= 256-byte block)
06430                 LDY MEMPTR+1            ;
06431                 CPY #$20                ;
06432                 TAY                     ;
06433                 BCC LOOP045             ; Loop until memory address $2000 reached
06434                 RTS                     ; Return
06435
06436 ;*******************************************************************************
06437 ;*                                                                             *
06438 ;*                                   TRIGGER                                   *
06439 ;*                                                                             *
06440 ;*                           Handle joystick trigger                           *
06441 ;*                                                                             *
06442 ;*******************************************************************************
06443
06444 ; DESCRIPTION
06445 ;
06446 ; This subroutine handles the joystick trigger and launches one of our
06447 ; starship's photon torpedo. If a target is in full lock-on then a second photon
06448 ; torpedo is prepared for automatic launch in the next game loop iteration.
06449 ;
06450 ; DETAILS
06451 ;
06452 ; If the trigger is pressed then reset the idle counter and, if not in
06453 ; hyperwarp, launch a photon torpedo with the following steps:
06454 ;
06455 ; (1)  If the trigger was pressed in this game loop iteration, a photon torpedo
06456 ;      will be launched if a previously launched photon torpedo is already under
06457 ;      way for at least 255 - 232 = 23 game loop iterations. This avoids firing
06458 ;      photon torpedoes too rapidly. 
06459 ;
06460 ; (2)  Start tracking a space object. If it is in full lock-on, set up the
06461 ;      lock-on timer, activate photon torpedo tracking, and tweak the last saved
06462 ;      trigger state such that our other photon torpedo (if available) is
06463 ;      launched automatically in the next game loop iteration.
06464 ;
06465 ; (3)  If the Photon Torpedoes are destroyed, do nothing.
06466 ;
06467 ; (4)  If the Photon Torpedoes are damaged, launch a photon torpedo from the
06468 ;      same barrel than the previous one. 
06469 ;
06470 ; (5)  If the Photon Torpedoes are not damaged, launch a photon torpedo from the
06471 ;      other barrel. 
06472 ;
06473 ; (6)  Set the lifetime of our starship's photon torpedo to infinite, set the
06474 ;      PLAYER shape to PHOTON TORPEDO. 
06475 ;
06476 ; (7)  Initialize the position vector of our starship's photon torpedo to:
06477 ;
06478 ;          x-coordinate := +256 (+$0100) <KM> (Right barrel)
06479 ;                          -256 (-$FF00) <KM> (Left barrel)
06480 ;          y-coordinate := -256 (-$FF00) <KM>
06481 ;          z-coordinate :=   +1 (+$0001) <KM>
06482 ;
06483 ; (8)  Initialize the velocity vector of our starship's photon torpedo to:
06484 ;
06485 ;          x-velocity   :=   +0 <KM/H>
06486 ;          y-velocity   :=   +0 <KM/H>
06487 ;          z-velocity   := +102 <KM/H> (All views but Aft view)
06488 ;                          -102 <KM/H> (Aft view)
06489 ;
06490 ; (9)  Subtract 10 energy units for launching our starship's photon torpedo.
06491 ;
06492 ; (10) Play the noise sound pattern PHOTON TORPEDO LAUNCHED by continuing code
06493 ;      execution into subroutine NOISE ($AEA8).
06494
06495 TRIGGER         LDA OLDTRIG0            ; Prep last trigger state
06496
06497                 LDY TRIG0               ; Copy current trigger state
06498                 STY OLDTRIG0            ;
06499                 BNE SKIP124             ; Return if trigger currently not pressed
06500
06501                 STY IDLECNTHI           ; Reset idle counter
06502
06503                 LDX WARPSTATE           ; Return if hyperwarp engaged
06504                 BNE SKIP124             ;
06505
06506                 LDX BARRELNR            ; Prep barrel number (0 -> left, 1 -> right)
06507
06508                 CMP #1                  ; If trigger is newly pressed -> handle tracking...
06509                 BEQ SKIP125             ; ...and launch our starship's photon torpedo...
06510                 BCS SKIP127             ; ...else launch our starship's photon torpedo only
06511 SKIP124         RTS                     ; Return
06512
06513 ;*** Set up our starship's photon torpedo tracking *****************************
06514 SKIP125         LDA PL3LIFE,X           ; Return if torpedo's lifetime >= 232 game loops
06515                 CMP #232                ;
06516                 BCS SKIP124             ;
06517
06518                 LDY TRACKDIGIT          ; Store index of tracked space object
06519                 STY PLTRACKED           ;
06520
06521                 LDA #12                 ; Prep lock-on lifetime := 12 game loops
06522                 LDY ISINLOCKON          ; If target is in full lock-on...
06523                 STY ISTRACKING          ; ...activate photon torpedo tracking
06524
06525                 BEQ SKIP126             ; Skip if target not in full lock-on
06526                 LDA #0                  ; Prep lock-on lifetime := 0 game loops
06527 SKIP126         STA LOCKONLIFE          ; Store lock-on lifetime (either 0 or 12 game loops)
06528
06529 ;*** Launch our starship's photon torpedo **************************************
06530 SKIP127         STY OLDTRIG0            ; Update last trigger state
06531                 BIT GCSTATPHO           ; Return if Photon Torpedoes are destroyed
06532                 BVS SKIP124             ;
06533
06534                 BMI SKIP128             ; If Photon Torpedoes damaged launch from same barrel
06535                 TXA                     ; ...else switch barrel from which to launch torpedo
06536                 EOR #$01                ;
06537                 STA BARRELNR            ;
06538
06539 SKIP128         TXA                     ; SUMMARY: Our starship's photon torpedo's...
06540                 STA PL3XPOSSIGN,X       ; x-coordinate := +256 (+$0100) <KM> (right barrel)
06541                 LDA BARRELXTAB,X        ; x-coordinate := -256 (-$FF00) <KM> (left barrel)
06542                 STA PL3XPOSHI,X         ; y-coordinate := -256 (-$FF00) <KM>
06543                 LDA #255                ; z-coordinate :=   +1 (+$0001) <KM>
06544                 STA PL3LIFE,X           ; ...lifetime := 255 game loops
06545                 STA PL3YPOSHI,X         ;
06546                 LDA #0                  ;
06547                 STA PL3SHAPTYPE,X       ; PLAYER3 or PLAYER4 is PHOTON TORPEDO (shape type 0)
06548                 STA PL3ZPOSHI,X         ;
06549                 STA PL3XPOSLO,X         ;
06550                 STA PL3YPOSSIGN,X       ;
06551                 STA PL3YPOSLO,X         ;
06552                 LDA #1                  ;
06553                 STA PL3ZPOSSIGN,X       ;
06554                 STA PL3ZPOSLO,X         ;
06555
06556                 LDA SHIPVIEW            ; SUMMARY: Our starship's photon torpedo's...
06557                 LSR A                   ; x-velocity :=   +0 <KM/H>
06558                 ROR A                   ; y-velocity :=   +0 <KM/H>
06559                 ORA #102                ; z-velocity := +102 <KM/H> (Other views)
06560                 STA PL3ZVEL,X           ; z-velocity := -102 <KM/H> (Aft view)
06561                 LDA #0                  ;
06562                 STA PL3XVEL,X           ;
06563                 STA PL3YVEL,X           ;
06564
06565                 LDX #2                  ; ENERGY := ENERGY - 10 for launching photon torpedo
06566                 JSR DECENERGY           ;
06567
06568                 LDX #$00                ; Play noise sound pattern PHOTON TORPEDO LAUNCHED
06569
06570 ;*******************************************************************************
06571 ;*                                                                             *
06572 ;*                                    NOISE                                    *
06573 ;*                                                                             *
06574 ;*                          Copy noise sound pattern                           *
06575 ;*                                                                             *
06576 ;*******************************************************************************
06577
06578 ; DESCRIPTION
06579 ;
06580 ; Copies a 10-byte noise sound pattern from table NOISEPATTAB ($BF20). The first
06581 ; 8 bytes are copied to the noise sound pattern area NOISETORPTIM
06582 ; ($DA)..NOISELIFE ($E1), the remaining 2 bytes are copied to audio registers
06583 ; AUDCTL ($D208) and AUDF3 ($D204). The noise sound pattern is automatically
06584 ; played in subroutine SOUND ($B2AB).
06585 ;
06586 ; NOTE: The first 8 bytes of each pattern in table NOISEPATTAB ($BF20) are
06587 ; copied in reverse order from memory. See subroutine SOUND ($B2AB) for details
06588 ; on the noise sound patterns stored in NOISEPATTAB ($BF20).
06589 ;
06590 ; Playing a SHIELD EXPLOSION or ZYLON EXPLOSION noise sound pattern overrides a
06591 ; currently playing PHOTON TORPEDO LAUNCHED noise sound pattern.
06592 ;
06593 ; Playing a PHOTON TORPEDO LAUNCHED noise sound pattern overrides a currently
06594 ; playing PHOTON TORPEDO LAUNCHED noise sound pattern if the latter has < 24
06595 ; TICKs to play.
06596 ;
06597 ; INPUT
06598 ;
06599 ;   X = Offset into table NOISEPATTAB ($BF20) to index noise sound patterns.
06600 ;       Used values are:
06601 ;     $00 -> PHOTON TORPEDO LAUNCHED
06602 ;     $0A -> SHIELD EXPLOSION (either our starship or a starbase explodes)
06603 ;     $14 -> ZYLON EXPLOSION
06604
06605 NOISE           TXA                     ; Skip if SHIELD EXPLOSION or ZYLON EXPLOSION playing
06606                 BNE SKIP129             ;
06607
06608                 LDA NOISELIFE           ; Return if PHOTON TORPEDO LAUNCHED noise sound pat.
06609                 CMP #24                 ; ...playing for yet more than 24 TICKs
06610                 BCS SKIP130             ;
06611
06612 SKIP129         LDY #7                  ; Copy noise sound pattern (in reverse order)
06613 LOOP046         LDA NOISEPATTAB,X       ;
06614                 STA NOISETORPTIM,Y      ;
06615                 INX                     ;
06616                 DEY                     ;
06617                 BPL LOOP046             ;
06618
06619                 LDA NOISEPATTAB,X       ; Copy AUDCTL from noise sound pattern table
06620                 STA AUDCTL              ;
06621                 LDA NOISEPATTAB+1,X     ; Copy AUDF3 from noise sound pattern table
06622                 STA AUDF3               ;
06623
06624 SKIP130         RTS                     ; Return
06625
06626 ;*******************************************************************************
06627 ;*                                                                             *
06628 ;*                                  HOMINGVEL                                  *
06629 ;*                                                                             *
06630 ;*      Calculate homing velocity of our starship's photon torpedo 0 or 1      *
06631 ;*                                                                             *
06632 ;*******************************************************************************
06633
06634 ; DESCRIPTION
06635 ;
06636 ; Calculates the x (or y) velocity vector component of our starship's photon
06637 ; torpedo 0 or 1 when it is tracking (homing in on) a target space object.
06638 ;
06639 ; Our starship's photon torpedo's x (or y) velocity vector component depends on
06640 ; the PLAYER column (or row) number difference between the target PLAYER and our
06641 ; starship's photon torpedo PLAYER in Player/Missile (PM) pixels. This
06642 ; difference is used as an index to pick the new x (or y) velocity vector
06643 ; component of our starship's photon torpedo from table HOMVELTAB ($BFC9):
06644 ;
06645 ; +---------------+--------------+
06646 ; | Difference in | New Velocity |
06647 ; |   PM Pixels   |  Component   |
06648 ; +---------------+--------------+
06649 ; |    >= +7      |   -64 <KM/H> |
06650 ; |       +6      |   -56 <KM/H> |
06651 ; |       +5      |   -48 <KM/H> |    
06652 ; |       +4      |   -40 <KM/H> |
06653 ; |       +3      |   -24 <KM/H> |
06654 ; |       +2      |   -16 <KM/H> |    
06655 ; |       +1      |    -8 <KM/H> |
06656 ; |        0      |     0 <KM/H> |
06657 ; |       -1      |    +8 <KM/H> |    
06658 ; |       -2      |   +16 <KM/H> |
06659 ; |       -3      |   +24 <KM/H> |
06660 ; |       -4      |   +40 <KM/H> |    
06661 ; |       -5      |   +48 <KM/H> |
06662 ; |       -6      |   +56 <KM/H> |    
06663 ; |    <= -7      |   +64 <KM/H> |
06664 ; +---------------+--------------+      
06665 ;
06666 ; INPUT
06667 ;
06668 ;   A     = PLAYER column (or row) number difference between the target PLAYER
06669 ;           and our starship's photon torpedo PLAYER in Player/Missile pixels
06670 ;
06671 ;   CARRY = Sign of the PLAYER column (or row) number difference. Used values
06672 ;           are:
06673 ;     0 -> Negative difference (target PLAYER column (or row) number < our
06674 ;          starship's photon torpedo PLAYER column (or row) number
06675 ;     1 -> Positive difference (target PLAYER column (or row) number >= our
06676 ;          starship's photon torpedo PLAYER column (or row) number
06677 ;
06678 ; OUTPUT
06679 ;
06680 ;   A = New velocity vector component of our starship's photon torpedo in <KM/H>
06681
06682 L.VELSIGN       = $6A                   ; Saves velocity sign
06683
06684 HOMINGVEL       LDY #NEG                ; Preload negative velocity sign
06685                 BCS SKIP131             ; Skip if difference is positive
06686
06687                 EOR #$FF                ; Invert to get absolute value of difference
06688                 LDY #0                  ; Preload positive velocity sign
06689
06690 SKIP131         STY L.VELSIGN           ; Save velocity sign
06691                 CMP #8                  ;
06692                 BCC SKIP132             ;
06693                 LDA #7                  ; Limit difference to 0..7
06694 SKIP132         TAY                     ;
06695                 LDA L.VELSIGN           ; Reload velocity sign
06696                 ORA HOMVELTAB,Y         ; Combine with homing velocity from table
06697                 RTS                     ; Return
06698
06699 ;*******************************************************************************
06700 ;*                                                                             *
06701 ;*                                   DAMAGE                                    *
06702 ;*                                                                             *
06703 ;*             Damage or destroy one of our starship's subsystems              *
06704 ;*                                                                             *
06705 ;*******************************************************************************
06706
06707 ; DESCRIPTION
06708 ;
06709 ; Damages or destroys one of our starship's subsystems. There are 6 subsystems:
06710 ;
06711 ; (1)  Photon Torpedoes
06712 ; (2)  Engines
06713 ; (3)  Shields
06714 ; (4)  Attack Computer
06715 ; (5)  Long-Range Scan
06716 ; (6)  Subspace Radio
06717 ;
06718 ; Their status is stored and displayed in the Galactic Chart Panel Display by
06719 ; the colored letters PESCLR. The color of each letter represents the
06720 ; subsystem's status:
06721 ;
06722 ; +---------------+------------------+
06723 ; | Letter Color  | Subsystem Status |
06724 ; +---------------+------------------+
06725 ; | {LIGHT GREEN} | OK               |
06726 ; | {CORN YELLOW} | Damaged          |
06727 ; | {PINK}        | Destroyed        |
06728 ; +---------------+------------------+
06729 ;
06730 ; This subroutine first makes sure that we are not in demo mode. Then it picks a
06731 ; random value in 0..255 and the damage probability value. The latter value
06732 ; depends on the mission level and is picked from table DAMAGEPROBTAB ($BF10):
06733 ;
06734 ; +-----------+-------------------+---------------+
06735 ; |  Mission  |       Damage      |    Damage     |
06736 ; |   Level   | Probability Value |  Probability  |
06737 ; +-----------+-------------------+---------------+
06738 ; | NOVICE    |          0        |  0% (  0:256) | 
06739 ; | PILOT     |         80        | 31% ( 80:256) |
06740 ; | WARRIOR   |        180        | 70% (180:256) |
06741 ; | COMMANDER |        254        | 99% (254:256) |
06742 ; +-----------+-------------------+---------------+
06743 ;
06744 ; If the random number is lower than the damage probability value, a randomly
06745 ; picked subsystem is about to get damaged (or destroyed). There is a built-in
06746 ; upfront probability of 25% (2:8) that no subsystem gets harmed.
06747 ;
06748 ; If the picked subsystem is already destroyed then another subsystem is picked.
06749 ;
06750 ; Then the title phrase offset is picked from table DAMAGEPHRTAB ($BF14) to
06751 ; display the damaged subsystem in the title line. Next, color bits are picked
06752 ; that indicate a damaged system.
06753 ;
06754 ; If the Zylon photon torpedo's lifetime >= 30 game loop iterations the
06755 ; subsystem will not only be damaged but destroyed.
06756 ;
06757 ; NOTE: The Zylon photon torpedo lifetime decreases from 62 to 0 game loop
06758 ; iterations. With a remaining lifetime >= 30 game loop iterations it is
06759 ; considered strong enough to destroy one of our starship's subsystems. There
06760 ; are two exceptions to this rule: If the Attack Computer was picked to be
06761 ; destroyed it will be damaged only - not destroyed - if the Long-Range Scan has
06762 ; been already destroyed, and vice versa.
06763 ;
06764 ; Then the title phrase offset from table DESTROYPHRTAB ($BF1A) is picked to
06765 ; display the destroyed subsystem in the title line. Next, color bits are picked
06766 ; that indicate a destroyed system.
06767 ;
06768 ; The color of the subsystem's status letter is adjusted in the Galactic Chart
06769 ; Panel Display. Next, the title phrase describing the subsystem's status is
06770 ; enqueued for display in the title line. If the Attack Computer has been
06771 ; destroyed it is switched off and the PLAYFIELD is cleared. The title line is
06772 ; updated with the "DAMAGE CONTROL" message. Finally, the beeper sound pattern
06773 ; DAMAGE REPORT is played in subroutine BEEP ($B3A6).
06774
06775 DAMAGE          BIT ISDEMOMODE          ; Return if in demo mode
06776                 BMI SKIP137             ;
06777
06778 ;*** Damage some subsystem *****************************************************
06779                 LDX MISSIONLEVEL        ; Prep mission level
06780 LOOP047         LDA RANDOM              ; Return if random number >= damage probability
06781                 CMP DAMAGEPROBTAB,X     ; ...(the latter depends on mission level)
06782                 BCS SKIP137             ;
06783
06784                 AND #$07                ; Randomly pick 1 of 6 subsystems
06785                 CMP #6                  ; Return if no subsystem picked
06786                 BCS SKIP137             ;
06787
06788                 TAX                     ;
06789                 LDA GCSTATPHO,X         ; Get picked subsystem status letter
06790                 ASL A                   ; Check bit B6 (= destroyed) of letter code
06791                 BMI LOOP047             ; Try again if subsystem already destroyed
06792
06793                 LDA PL2LIFE             ; Load Zylon photon torpedo lifetime...
06794                 CMP #30                 ; ...and compare it to 30 game loops
06795
06796                 LDA #CCS.COL2           ; Preload COLOR2 text color bits (= damaged status)
06797                 LDY DAMAGEPHRTAB,X      ; Preload title phrase offset of damaged subsystem
06798
06799                 BCC SKIP135             ; Skip if Zylon torpedo lifetime < 30 game loops
06800
06801                 CPX #3                  ; Skip if selected subsystem not Attack Computer
06802                 BNE SKIP133             ;
06803                 BIT GCSTATLRS           ; Skip if Long-Range Scan already destroyed
06804                 BVS SKIP135             ;
06805 SKIP133         CPX #4                  ; Skip if selected subsystem is not Long-Range Scan
06806                 BNE SKIP134             ;
06807                 BIT GCSTATCOM           ; Skip if Attack Computer already destroyed
06808                 BVS SKIP135             ;
06809
06810 SKIP134         LDA #CCS.COL3           ; Preload COLOR3 text color bits (= destroyed status)
06811                 LDY DESTROYPHRTAB,X     ; Preload title phrase offset of destroyed subsystem
06812
06813 SKIP135         ORA GCSTATPHO,X         ; Combine status letter with new color
06814                 STA GCSTATPHO,X         ;
06815                 STY NEWTITLEPHR         ; Enqueue damage status title phrase
06816                 BIT GCSTATCOM           ; Skip if Attack Computer OK or damaged
06817                 BVC SKIP136             ;
06818
06819                 LDA #0                  ; Switch Attack Computer off
06820                 STA DRAINATTCOMP        ;
06821                 JSR CLRPLAYFIELD        ; Clear PLAYFIELD
06822
06823 SKIP136         LDY #$52                ; Set title phrase "DAMAGE CONTROL..."
06824                 JSR SETTITLE            ;
06825
06826                 LDX #$12                ; Play beeper sound pattern DAMAGE REPORT
06827                 JSR BEEP                ;
06828
06829 SKIP137         RTS                     ; Return
06830
06831 ;*******************************************************************************
06832 ;*                                                                             *
06833 ;*                                  COLLISION                                  *
06834 ;*                                                                             *
06835 ;*            Detect a collision of our starship's photon torpedoes            *
06836 ;*                                                                             *
06837 ;*******************************************************************************
06838
06839 ; DESCRIPTION
06840 ;
06841 ; Both of our starship's photon torpedoes are checked if they have collided with
06842 ; a space object represented by PLAYER0..2, such as a Zylon ship, a Zylon photon
06843 ; torpedo, a starbase, or a meteor. 
06844 ;
06845 ; For quick lookup, the following table lists the PLAYERs and what space objects
06846 ; they represent:
06847 ;
06848 ; +--------+--------------------------------------------------+
06849 ; | PLAYER |                   Represents                     |
06850 ; +--------+--------------------------------------------------+
06851 ; |   0    | Zylon ship 0, Starbase Left                      |
06852 ; |   1    | Zylon ship 1, Starbase Right                     |
06853 ; |   2    | Zylon photon torpedo, Starbase Center, Meteor    | 
06854 ; |   3    | Our starship's photon torpedo 0                  |
06855 ; |   4    | Our starship's photon torpedo 1, Transfer Vessel |
06856 ; +--------+--------------------------------------------------+
06857 ;
06858 ; NOTE: Only space objects represented by PLAYER0..2 are checked for collisions.
06859 ; The transfer vessel of the starbase, represented by PLAYER4, is not checked
06860 ; and therefore cannot be destroyed by one of our starship's photon torpedoes.
06861 ;
06862 ; This subroutine first checks if our starship's photon torpedoes are
06863 ; represented by alive PLAYERs with PHOTON TORPEDO shape.
06864 ;
06865 ; In order to detect a collision with a space object, our starship's photon
06866 ; torpedo must compare its x, y, and z coordinates with the ones of the space
06867 ; object.
06868 ;
06869 ; Instead of comparing the x and y coordinates, however, this subroutines uses a
06870 ; much more efficient method by inspecting the Player/Missile collision
06871 ; registers, as the x and y axis of the 3D coordinate system establish the plane
06872 ; in which the TV screen lies. Each of our starship's photon torpedoes has its
06873 ; own Player/Missile collision register: PL3HIT ($82) for our starship's photon
06874 ; torpedo 0 and PL4HIT ($83) for our starship's photon torpedo 1. By inspecting
06875 ; these registers the hit space object is determined: 
06876 ;
06877 ; +---------------------------------------------------+-------------------------+
06878 ; |          Bits B2..0 of Collision Register         |        Hit PLAYER       |
06879 ; |              (0 -> Not Hit, 1 -> Hit)             |                         |
06880 ; +-----------------+----------------+----------------+                         |
06881 ; |     PLAYER2     |     PLAYER1    |    PLAYER0     |                         |
06882 ; | (Zylon torpedo) | (Zylon ship 1) | (Zylon ship 0) |                         |
06883 ; +-----------------+----------------+----------------+-------------------------+
06884 ; |        0        |        0       |        0       | None                    |
06885 ; |        0        |        0       |        1       | PLAYER0 (Zylon ship 0)  |
06886 ; |        0        |        1       |        0       | PLAYER1 (Zylon ship 1)  |
06887 ; |        0        |        1       |        1       | PLAYER1 (Zylon ship 1)  |
06888 ; |        1        |        0       |        0       | PLAYER2 (Zylon torpedo) |
06889 ; |        1        |        0       |        1       | PLAYER2 (Zylon torpedo) |
06890 ; |        1        |        1       |        0       | PLAYER1 (Zylon ship 1)  |
06891 ; |        1        |        1       |        1       | PLAYER1 (Zylon ship 1)  |
06892 ; +-----------------+----------------+----------------+-------------------------+
06893 ;
06894 ; If the lifetime of the hit space object has already expired, then the hit is
06895 ; ignored.
06896 ;
06897 ; A collision along the z-axis happens if the z-coordinate of our starship's
06898 ; photon torpedo is close enough to the z-coordinate of the space object. This
06899 ; is determined as follows:
06900 ;
06901 ; The absolute value of the z-coordinate of the space object is converted into a
06902 ; range index in 0..7. This index picks a minimum and a maximum z-coordinate
06903 ; from tables HITMINZTAB ($BF7D) and HITMAXZTAB ($BF75). If the absolute value
06904 ; of the z-coordinate of our starship's photon torpedo is inside this interval,
06905 ; then our starship's photon torpedo has hit the space object. The following
06906 ; table lists the relevant values: 
06907 ;
06908 ; +-----------------------+-------+--------------------------+--------------------------+
06909 ; | ABS(z-Coordinate)     | Range | Min ABS(z-Coordinate)    | Max ABS(z-Coordinate)    |
06910 ; | of Space Object       | Index | of Photon Torpedo to Hit | of Photon Torpedo to Hit |
06911 ; +-----------------------+-------+--------------------------+--------------------------+
06912 ; | <=   511 ($01**) <KM> |   0   |           0 ($00**) <KM> |      < 3328 ($0C**) <KM> |
06913 ; | <=  1023 ($03**) <KM> |   1   |           0 ($00**) <KM> |      < 3328 ($0C**) <KM> |
06914 ; | <=  1535 ($05**) <KM> |   2   |           0 ($00**) <KM> |      < 3328 ($0C**) <KM> |
06915 ; | <=  2047 ($07**) <KM> |   3   |         512 ($02**) <KM> |      < 3328 ($0C**) <KM> |
06916 ; | <=  2559 ($09**) <KM> |   4   |        1024 ($04**) <KM> |      < 3840 ($0E**) <KM> |
06917 ; | <=  3071 ($0B**) <KM> |   5   |        1536 ($06**) <KM> |      < 3840 ($0E**) <KM> |
06918 ; | <=  3583 ($0D**) <KM> |   6   |        2048 ($08**) <KM> |      < 3840 ($0E**) <KM> |
06919 ; | <= 65535 ($FF**) <KM> |   7   |        3072 ($0C**) <KM> |      < 8448 ($20**) <KM> |
06920 ; +-----------------------+-------+--------------------------+--------------------------+
06921 ;
06922 ; If a collision has been detected, the "age" (= initial lifetime - remaining
06923 ; lifetime) of our starship's photon torpedo is calculated. This age is used to
06924 ; delay playing the ZYLON EXPLOSION noise sound pattern. It is also used to
06925 ; determine the strength of our starship's photon torpedo. Only photon torpedoes
06926 ; of an age < 15 game loop iterations can destroy a Zylon basestar.
06927 ;
06928 ; Some clean-up work is done before the actual explosion: The lock-on timer, our
06929 ; starship's photon torpedo lifetime, and the hit space object's PLAYER lifetime
06930 ; is set to 0. 
06931 ;
06932 ; If a meteor or a Zylon photon torpedo have been hit, then the score is not
06933 ; changed, skipping right to the explosion part. Otherwise, our starship's
06934 ; photon torpedo tracking flag is cleared and the Galactic Chart Map is updated.
06935 ; If a starbase was destroyed, then 3 points are subtracted from the score. If a
06936 ; Zylon ship was destroyed, then 6 points are added to the score and the Zylon
06937 ; KILL COUNTER readout of the Control Panel Display is incremented. Next, the
06938 ; explosion is initialized in subroutine INITEXPL ($AC6B).
06939 ;
06940 ; NOTE: This subroutine lacks proper explosion initialization if the starbase
06941 ; was hit. The actual explosion initialization is done in subroutine DOCKING
06942 ; ($ACE6) when the code finds out that the starbase sector is no more marked as
06943 ; such in the Galactic Chart.
06944 ;
06945 ; Finally, the Galactic Chart Map is searched for a remaining Zylon unit. If
06946 ; none is found then the mission is complete and code execution continues into
06947 ; subroutine GAMEOVER2 ($B121), ending the game. 
06948
06949 L.PLHIT         = $6B                   ; Saves PLAYER (and space object) index of hit PLAYER
06950 L.VIEWDIR       = $6C                   ; Saves view direction. Used values are:
06951                                         ;   $00 -> Front view
06952                                         ;   $FF -> Aft view
06953
06954 COLLISION       LDX #2                  ; Loop over our starship's two photon torpedoes
06955 LOOP048         DEX                     ;
06956                 BPL SKIP138             ; Branch into loop body below
06957                 RTS                     ; Return
06958
06959 ;*** Photon torpedo sanity checks **********************************************
06960 SKIP138         LDA PL3SHAPTYPE,X       ; Next photon torpedo if PLAYER not a PHOTON TORPEDO
06961                 BNE LOOP048             ;
06962
06963                 LDA PL3LIFE,X           ; Next photon torpedo if PLAYER not alive
06964                 BEQ LOOP048             ;
06965
06966 ;*** Check if our starship's photon torpedo has hit in x-y plane ***************
06967                 LDA PL3HIT,X            ; Check Player/Missile collision register
06968                 AND #$07                ; Next torpedo if no torpedo-to-PLAYER collision
06969                 BEQ LOOP048             ;
06970
06971                 LSR A                   ; Find out which of PLAYER0..2 was hit in PLAYFIELD
06972                 CMP #3                  ;
06973                 BNE SKIP139             ;
06974                 LSR A                   ;
06975 SKIP139         TAY                     ; Save resulting index of hit PLAYER
06976
06977                 LDA PL0LIFE,Y           ; Next torpedo if PLAYER0..2 (= targets) not alive
06978                 BEQ LOOP048             ;
06979
06980 ;*** Has our starship's photon torpedo hit within valid z-coordinate interval? *
06981                 LDA SHIPVIEW            ; Skip if in Front view
06982                 BEQ SKIP140             ;
06983                 LDA #$FF                ; Calculate range index...
06984 SKIP140         STA L.VIEWDIR           ; Saves view direction
06985                 EOR ZPOSHI,Y            ; Calc ABS(z-coordinate (high byte)) of hit object
06986                 CMP #16                 ; Limit range index to 0..7
06987                 BCC SKIP141             ;
06988                 LDA #15                 ;
06989 SKIP141         LSR A                   ;
06990                 STY L.PLHIT             ; Save index of hit PLAYER
06991
06992                 TAY                     ;
06993                 LDA L.VIEWDIR           ; Reload view direction
06994                 EOR PL3ZPOSHI,X         ; Calc ABS(z-coordinate (high byte)) of torpedo
06995
06996                 CMP HITMAXZTAB,Y        ; Next torpedo if torpedo >= max hit z-coordinate
06997                 BCS LOOP048             ;
06998
06999                 CMP HITMINZTAB,Y        ; Next torpedo if torpedo < min hit z-coordinate
07000                 BCC LOOP048             ;
07001
07002 ;*** Our starship's photon torpedo has hit within valid z-coordinate interval! *
07003                 LDY L.PLHIT             ; Reload index of hit PLAYER
07004                 SEC                     ; Calc "age" of photon torpedo in game loops to...
07005                 LDA #255                ; delay playing ZYLON EXPLOSION noise sound pattern
07006                 SBC PL3LIFE,X           ;
07007                 STA NOISEZYLONTIM       ;
07008
07009                 CMP #15                 ; Skip if photon torpedo "age" < 15
07010                 BCC SKIP142             ;
07011                 LDA PL0SHAPTYPE,Y       ; CARRY := PLAYER is ZYLON BASESTAR (shape type 8)
07012                 CMP #SHAP.ZBASESTAR     ; (and torpedo "age" good to destroy ZYLON BASESTAR)
07013
07014 ;*** Clean up our starship's photon torpedo and hit PLAYER *********************
07015 SKIP142         LDA #0                  ; Lock-on lifetime := 0 game loops
07016                 STA LOCKONLIFE          ;
07017                 STA PL3LIFE,X           ; Photon torpedo's lifetime := 0 game loops
07018                 BCS SKIP144             ; If CARRY set do not score, just do explosion
07019
07020                 STA PL0LIFE,Y           ; Hit PLAYER lifetime := 0 game loops
07021
07022                 LDA PL0SHAPTYPE,Y       ; If hit PLAYER is...
07023                 BEQ SKIP144             ; ...a PHOTON TORPEDO (shape type 0)...
07024                 CMP #SHAP.METEOR        ; ...or a METEOR (shape type 6)...
07025                 BEQ SKIP144             ; ...do not score, just do explosion
07026
07027                 LDA #0                  ; Clear photon torpedo tracking flag
07028                 STA ISTRACKING          ;
07029
07030 ;*** Zylon ship (or starbase) destroyed! ***************************************
07031                 LDX CURRSECTOR          ; Decrement Zylon count on Galactic Chart
07032                 DEC GCMEMMAP,X          ;
07033                 BPL SKIP143             ; Skip if destroyed space object was Zylon ship
07034
07035 ;*** Starbase destroyed! *******************************************************
07036                 LDA #0                  ; Remove destroyed starbase from Galactic Chart
07037                 STA GCMEMMAP,X          ;
07038                 SEC                     ; SCORE := SCORE - 3 for destroying starbase
07039                 LDA SCORE               ;
07040                 SBC #3                  ;
07041                 STA SCORE               ;
07042                 LDA SCORE+1             ;
07043                 SBC #0                  ;
07044                 STA SCORE+1             ;
07045                 RTS                     ; Return
07046
07047 ;*** Zylon ship destroyed! *****************************************************
07048 SKIP143         CLC                     ; SCORE := SCORE + 6 for destroying Zylon ship
07049                 LDA SCORE               ;
07050                 ADC #6                  ;
07051                 STA SCORE               ;
07052                 LDA SCORE+1             ;
07053                 ADC #0                  ;
07054                 STA SCORE+1             ;
07055
07056                 LDX #1                  ; Increment Zylon KILL COUNTER readout...
07057 LOOP049         INC KILLCNTD1,X         ; ...of Control Panel Display
07058                 LDA KILLCNTD1,X         ;
07059                 CMP #[CCS.COL1!CCS.9]+1 ;
07060                 BCC SKIP144             ;
07061                 LDA #[CCS.COL1!CCS.0]   ;
07062                 STA KILLCNTD1,X         ;
07063                 DEX                     ;
07064                 BPL LOOP049             ;
07065
07066 SKIP144         JSR INITEXPL            ; Init explosion at hit PLAYER
07067
07068 ;*** Any Zylon ships left? *****************************************************
07069                 LDX #127                ; Scan all sectors of Galactic Chart
07070 LOOP050         LDA GCMEMMAP,X          ;
07071                 BMI SKIP145             ;
07072                 BNE SKIP146             ; Return if Zylon sector found
07073 SKIP145         DEX                     ;
07074                 BPL LOOP050             ;
07075
07076 ;*** Game over (Mission Complete) **********************************************
07077                 LDY #$3F                ; Set title phrase "MISSION COMPLETE"
07078                 LDX #0                  ; Set mission bonus offset
07079                 JSR GAMEOVER2           ; Game over
07080 SKIP146         RTS                     ; Return
07081
07082 ;*******************************************************************************
07083 ;*                                                                             *
07084 ;*                                  KEYBOARD                                   *
07085 ;*                                                                             *
07086 ;*                            Handle Keyboard Input                            *
07087 ;*                                                                             *
07088 ;*******************************************************************************
07089
07090 ; DESCRIPTION
07091 ;
07092 ; If a keyboard code has been collected during a keyboard IRQ in the Immediate
07093 ; Interrupt Request handler IRQHNDLR ($A751), the idle counter is reset and the
07094 ; PLAYER-PLAYFIELD priority arranges the PLAYERs in front of the PLAYFIELD.
07095 ;
07096 ; Then, the keyboard code is compared with keyboard codes of table KEYTAB
07097 ; ($BABE). If no match is found the "WHAT'S WRONG" message is displayed in the
07098 ; title line and code execution returns.
07099 ;
07100 ; If one of the speed keys '0'..'9' has been pressed, a pending hyperwarp is
07101 ; aborted in subroutine ABORTWARP ($A980) and code execution returns. Otherwise
07102 ; the Engines drain rate is adjusted as well as the new velocity of our
07103 ; starship. If the Engines are damaged, a maximum speed is possible equivalent
07104 ; to speed key '5'.
07105 ;
07106 ; If one of our starship's view keys 'F' (Front), 'A' (Aft), 'G' (Galactic
07107 ; Chart), or 'L' (Long-Range Scan) have been pressed, the Display List is
07108 ; modified accordingly in subroutine MODDLST ($ADF1) and a new star field of 12
07109 ; stars is created with the help of subroutine INITPOSVEC ($B764). Code
07110 ; execution returns via subroutine UPDSCREEN ($B07B).
07111 ;
07112 ; If one of the 'T' (Tracking Computer), 'S' (Shields) or 'C' (Attack Computer)
07113 ; keys have been pressed, the corresponding status bits are toggled and the
07114 ; title line is updated with the corresponding title phrase. The beeper sound
07115 ; pattern ACKNOWLEDGE is played in subroutine BEEP ($B3A6). The tracking letter
07116 ; of the Control Panel Display is updated and the PLAYFIELD is cleared in
07117 ; subroutine CLRPLAYFIELD ($AE0D). If the Attack Computer is on, the Front or
07118 ; Aft view cross hairs are drawn, depending on the current view of our starship,
07119 ; via subroutine DRAWLINES ($A76F).
07120 ;
07121 ; If the 'H' (Hyperwarp) key has been pressed then the hyperwarp is engaged. Our
07122 ; starship's velocity is set to the maximum value, the Engines drain rate is
07123 ; increased to the equivalent of speed key '7'. Star trails are prepared. The
07124 ; position vector of the Hyperwarp Target Marker (PLAYER3) is set to the
07125 ; following values:
07126 ;
07127 ;     x-coordinate :=   +0 (+$0000) <KM>
07128 ;     y-coordinate := +256 (+$0100) <KM>
07129 ;     z-coordinate :=    + (+$****) <KM> (sign only)
07130 ;
07131 ; The velocity vector is set to the following values:
07132 ;
07133 ;     x-velocity   :=  (not initialized)
07134 ;     y-velocity   :=  (not initialized)
07135 ;     z-velocity   :=          +0 <KM/H>
07136 ;
07137 ; The temporary arrival hyperwarp marker column and row numbers are saved. If we
07138 ; are not in a NOVICE mission, the maximum veer-off velocity of the Hyperwarp
07139 ; Target Marker during hyperwarp is picked from table VEERMASKTAB ($BED7). This
07140 ; value depends on the selected hyperwarp energy (and thus on the distance to
07141 ; hyperwarp). Finally, the title line displays the "HYPERWARP ENGAGED" message.
07142 ;
07143 ; If the 'M' (Manual target selector) key has been pressed, the tracked target
07144 ; space object is swapped and the corresponding digit of the Control Panel
07145 ; Display is toggled between 0 and 1.
07146 ;
07147 ; If the 'P' (Pause) key has been pressed, an endless loop waits until the
07148 ; joystick is pushed.
07149 ;
07150 ; BUG (at $B103): The endless loop branches back one instruction too far.
07151 ; Suggested fix: Branch to instruction LDA PORTA at $B0FE.
07152 ;
07153 ; If the 'INV' (Abort mission) key has been pressed, the mission is aborted by
07154 ; setting the mission bonus offset, then displaying the "MISSION ABORTED"
07155 ; message in the title line. Code execution continues into subroutine GAMEOVER
07156 ; ($B10A).
07157 ;
07158 ; NOTE: This subroutine has two additional entry points:
07159 ;
07160 ; (1)  SETVIEW ($B045), which is used to enforce the Front view. It is entered
07161 ;      from the game loop GAMELOOP ($A1F3) and subroutines INITSTART ($A15E) and
07162 ;      DECENERGY ($B86F).
07163 ;
07164 ; (2)  UPDSCREEN ($B07B), which draws the cross hairs and the Attack Computer
07165 ;      Display, and then sets the tracking letter of the Control Panel Display.
07166 ;      It is entered from subroutine DOCKING ($ACE6).
07167
07168 L.KEYCODE       = $6A                   ; Saves pressed keyboard code
07169
07170 KEYBOARD        LDA KEYCODE             ; Return if no keyboard code collected
07171                 BEQ SKIP150             ;
07172
07173                 LDX #20                 ; Prep keyboard code table loop index
07174                 STA L.KEYCODE           ; Save keyboard code
07175
07176                 LDA #0                  ; Reset idle counter
07177                 STA IDLECNTHI           ;
07178                 STA KEYCODE             ; Clear keyboard code
07179
07180                 LDA #$11                ; GTIA: Enable PLAYER4, prio: PLs > PFs > BGR
07181                 STA PRIOR               ; (PLAYERs in front of stars - and cross hairs)
07182
07183 ;*** Search keyboard code in lookup table **************************************
07184
07185 LOOP051         LDA KEYTAB,X            ; Loop over all valid keyboard codes
07186                 CMP L.KEYCODE           ;
07187                 BEQ SKIP147             ; Branch if matching entry found
07188                 DEX                     ;
07189                 BPL LOOP051             ; Next keyboard code
07190
07191                 LDY #$10                ; No match found...
07192                 JMP SETTITLE            ; ...set title phrase "WHATS WRONG?" and return
07193
07194 ;*** Handle '0'..'9' keyboard keys (speed) *************************************
07195 SKIP147         CPX #10                 ; Skip section if keyboard code does not match
07196                 BCS SKIP151             ;
07197
07198                 LDA WARPSTATE           ; Skip if hyperwarp disengaged...
07199                 BEQ SKIP148             ;
07200                 JMP ABORTWARP           ; ...else abort hyperwarp
07201
07202 SKIP148         BIT GCSTATENG           ; Skip if Engines are OK or destroyed
07203                 BVC SKIP149             ;
07204                 CPX #6                  ; Allow max velocity equivalent to speed key '5'
07205                 BCC SKIP149             ;
07206                 LDX #5                  ;
07207
07208 SKIP149         LDA DRAINRATETAB,X      ; Set Engines energy drain rate
07209                 STA DRAINENGINES        ;
07210                 LDA VELOCITYTAB,X       ; Set new velocity
07211                 STA NEWVELOCITY         ;
07212 SKIP150         RTS                     ; Return
07213
07214 ;*** Handle 'F', 'A', 'L', 'G' keyboard keys (our starship's views) ************
07215 SKIP151         CPX #14                 ; Skip section if keyboard code does not match
07216                 BCS SKIP152             ;
07217
07218 ;*** Entry to force Front view after game init and failed missions *************
07219 SETVIEW         LDA VIEWMODETAB-10,X    ; Store our starship's view type
07220                 STA SHIPVIEW            ;
07221
07222                 LDY DLSTFRAGOFFTAB-10,X ; Get DL fragment offset (Front, Aft, LRS, GC)
07223                 LDX #$02                ; Switch to corresponding view
07224                 LDA #$08                ;
07225                 JSR MODDLST             ;
07226
07227                 LDX #NUMSPCOBJ.NORM-1   ; Create new star field of 12 stars
07228 LOOP052         JSR INITPOSVEC          ;
07229                 DEX                     ;
07230                 CPX #NUMSPCOBJ.PL       ;
07231                 BCS LOOP052             ;
07232
07233                 BCC UPDSCREEN           ; Return via updating screen (below)
07234
07235 ;*** Handle 'T', 'S', 'C' keyboard keys (Tracking, Shields, Attack Computer) ***
07236 SKIP152         CPX #17                 ; Skip section if keyboard code does not match
07237                 BCS SKIP156             ;
07238
07239                 LDY MSGOFFTAB-14,X      ; Prep title phrase offset "... OFF"
07240                 LDA ISTRACKCOMPON-14,X  ; Toggle status bits (also energy consumption values)
07241                 EOR MSGBITTAB-14,X      ;
07242                 STA ISTRACKCOMPON-14,X  ;
07243                 BEQ SKIP153             ;
07244                 LDY MSGONTAB-14,X       ; Prep title phrase offset "... ON"
07245 SKIP153         JSR SETTITLE            ; Set title phrase to "... ON" or "... OFF" version
07246
07247                 LDX #$0C                ; Play beeper sound pattern ACKNOWLEDGE
07248                 JSR BEEP                ;
07249
07250 ;*** Update PLAYFIELD (Cross hairs, Attack Computer, set tracking letter) ******
07251 UPDSCREEN       LDX #CCS.T              ; Get custom char 'T' (entry point TRANSFER COMPLETE)
07252                 LDY ISTRACKCOMPON       ;
07253                 BEQ SKIP154             ; Skip if Tracking Computer is on
07254
07255                 INX                     ; Get custom char 'C'
07256
07257 SKIP154         STX TRACKC1             ; Store tracking character in Control Panel Display
07258                 JSR CLRPLAYFIELD        ; Clear PLAYFIELD
07259                 LDA DRAINATTCOMP        ; Return if Attack Computer off
07260                 BEQ SKIP150             ;
07261
07262                 LDX SHIPVIEW            ; If Aft view   -> Draw Aft cross hairs and return
07263                 BEQ SKIP155             ; If Front view -> Draw Front cross hairs and ...
07264                 CPX #$01                ;                  ...Attack Computer and return
07265                 BNE SKIP150             ;
07266                 LDX #$2A                ;
07267 SKIP155         JMP DRAWLINES           ;
07268
07269 ;*** Handle 'H' keyboard key (Hyperwarp) ***************************************
07270 SKIP156         CPX #17                 ; Skip if keyboard code does not match
07271                 BNE SKIP158             ;
07272
07273 ;*** Engage Hyperwarp **********************************************************
07274                 LDA WARPSTATE           ; Return if hyperwarp engaged
07275                 BNE SKIP159             ;
07276
07277                 LDA #$7F                ; Engage hyperwarp
07278                 STA WARPSTATE           ;
07279                 LDA #255                ; Set new velocity
07280                 STA NEWVELOCITY         ;
07281                 LDA #30                 ; Set Engines energy drain rate (= speed key '7')
07282                 STA DRAINENGINES        ;
07283
07284                 LDA #NUMSPCOBJ.ALL-1    ; Set space obj index of first star of star trail
07285                 STA TRAILIND            ;
07286                 LDA #0                  ; Clear star trail delay
07287                 STA TRAILDELAY          ;
07288
07289                 STA PL3XPOSHI           ; Init position vector and velocity vector of...
07290                 STA PL3XPOSLO           ; ... Hyperwarp Target Marker (PLAYER3):
07291                 STA PL3YPOSLO           ; x-coordinate :=   +0 (+$0000) <KM>
07292                 STA PL3ZVEL             ; y-coordinate := +256 (+$0100) <KM>
07293                 LDA #1                  ; z-coordinate :=    + (+$****) <KM> (sign only)
07294                 STA PL3ZPOSSIGN         ; z-velocity := +0 <KM/H>
07295                 STA PL3XPOSSIGN         ;
07296                 STA PL3YPOSSIGN         ;
07297                 STA PL3YPOSHI           ;
07298
07299                 LDA WARPARRVCOLUMN      ; Store temp arrival hyperwarp marker column number
07300                 STA WARPTEMPCOLUMN      ;
07301                 LDA WARPARRVROW         ; Store temp arrival hyperwarp marker row number
07302                 STA WARPTEMPROW         ;
07303
07304                 LDA MISSIONLEVEL        ; Skip if NOVICE mission
07305                 BEQ SKIP157             ;
07306
07307                 LDA WARPENERGY          ; Bits B0..1 of hyperwarp energy index a table...
07308                 ROL A                   ; ...containing the maximum value of how much the...
07309                 ROL A                   ; ...Hyperwarp Target Marker will veer off during...
07310                 ROL A                   ; ...hyperwarp
07311                 AND #$03                ;
07312                 TAY                     ;
07313                 LDA VEERMASKTAB,Y       ;
07314
07315 SKIP157         STA VEERMASK            ; Store veer-off velocity limitation mask
07316
07317                 LDY #$11                ; Set title phrase "HYPERWARP ENGAGED" and return
07318                 JMP SETTITLE            ;
07319
07320 ;*** Handle 'M' keyboard key (Manual Target Selector) key **********************
07321 SKIP158         CPX #19                 ; Skip if keyboard code does not match
07322                 BCS SKIP160             ;
07323
07324                 LDA TRACKDIGIT          ; Toggle digit of tracked space object of...
07325                 EOR #$01                ; ... Control Panel Display
07326                 AND #$01                ;
07327                 STA TRACKDIGIT          ;
07328 SKIP159         RTS                     ; Return
07329
07330 ;*** Handle 'P' keyboard key (Pause) *******************************************
07331 SKIP160         BNE SKIP161             ; Skip if keyboard code does not match
07332
07333                 LDA PORTA               ; Push joystick to resume action
07334                 CMP #$FF                ;
07335                 BEQ SKIP160             ; (!)
07336                 RTS                     ; Return
07337
07338 ;*** Handle 'INV' keyboard key (Abort Mission) *********************************
07339 SKIP161         LDY #$76                ; Preload title phrase "MISSION ABORTED..."
07340                 LDX #$04                ; Set mission bonus offset
07341
07342 ;*******************************************************************************
07343 ;*                                                                             *
07344 ;*                                  GAMEOVER                                   *
07345 ;*                                                                             *
07346 ;*                              Handle game over                               *
07347 ;*                                                                             *
07348 ;*******************************************************************************
07349
07350 ; DESCRIPTION
07351 ;
07352 ; Handles game over, including calculating the scored rank and class.
07353 ;
07354 ; This subroutine has two entry points: 
07355 ;
07356 ; (1)  GAMEOVER ($B10A) is entered at the end of a failed mission (mission
07357 ;      aborted, zero energy, or starship destroyed by Zylon fire), essentially
07358 ;      shutting down our starship. Code execution continues into GAMEOVER2
07359 ;      ($B121) below.
07360 ;
07361 ; (2)  GAMEOVER2 ($B121) is entered at the end of a successful mission (all
07362 ;      Zylon ships destroyed). It puts the game in demo mode, enqueues the
07363 ;      corresponding game over message, and calculates the scored rank and
07364 ;      class.
07365 ;
07366 ;      The scored rank and class are based on the total score. This is the score
07367 ;      accumulated during the game plus a mission bonus, which depends on the
07368 ;      mission level and on how the mission ended (mission complete, mission
07369 ;      aborted, or starship destroyed by Zylon fire). The mission bonus is
07370 ;      picked from table BONUSTAB ($BEDD).
07371 ;
07372 ;      The scored rank index is taken from bits B8..4 of the total score and
07373 ;      limited to values of 0..18. It indexes table RANKTAB ($BEE9) for the rank
07374 ;      string. The rank string is displayed in subroutine SETTITLE ($B223).
07375 ;
07376 ;      The scored class index is taken from bits B3..0 (for rank indices 0,
07377 ;      11..14) and computed from bits B4..1 (for rank indices 1..10 and 15..18).
07378 ;      It takes values of 0..15. It indexes table CLASSTAB ($BEFC) for the class
07379 ;      digit. The class digit is displayed in subroutine SETTITLE ($B223).
07380 ;
07381 ;      For quick lookup, the following table lists rank and class from the total
07382 ;      score. Use the table as follows: Pick the cell with the closest value
07383 ;      less or equal to your score then read the rank and class off the left and
07384 ;      the top of the table, respectively.
07385 ;
07386 ;      For example: A score of 90 results in a ranking of "Novice Class 4", a
07387 ;      score of 161 results in a ranking of "Pilot Class 3".
07388 ;
07389 ; +------------------------------+---------------------------------------------------------------+
07390 ; |     Minimum Total Score      |                        Class Index                            |
07391 ; |                              |  0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15|
07392 ; +-------+----------------------+---------------------------------------------------------------+
07393 ; | Rank  |                      |                           Class                               |
07394 ; | Index |         Rank         |  5   5   5   4   4   4   4   3   3   3   2   2   2   1   1   1|
07395 ; +-------+----------------------+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
07396 ; |     0 | Galactic Cook        |  0|  1|  2|  3|  4|  5|  6|  7|  8|  9| 10| 11| 12| 13| 14| 15|
07397 ; |     1 | Garbage Scow Captain | 16| 18| 20| 22| 24| 26| 28| 30|   |   |   |   |   |   |   |   |
07398 ; |     2 | Garbage Scow Captain |   |   |   |   |   |   |   |   | 32| 34| 36| 38| 40| 42| 44| 46|
07399 ; |     3 | Rookie               | 48| 50| 52| 54| 56| 58| 60| 62|   |   |   |   |   |   |   |   |
07400 ; |     4 | Rookie               |   |   |   |   |   |   |   |   | 64| 66| 68| 70| 72| 74| 76| 78|
07401 ; |     5 | Novice               | 80| 82| 84| 86| 88| 90| 92| 94|   |   |   |   |   |   |   |   |
07402 ; |     6 | Novice               |   |   |   |   |   |   |   |   | 96| 98|100|102|104|106|108|110|
07403 ; |     7 | Ensign               |112|114|116|118|120|122|124|126|   |   |   |   |   |   |   |   |
07404 ; |     8 | Ensign               |   |   |   |   |   |   |   |   |128|130|132|134|136|138|140|142|
07405 ; |     9 | Pilot                |144|146|148|150|152|154|156|158|   |   |   |   |   |   |   |   |
07406 ; |    10 | Pilot                |   |   |   |   |   |   |   |   |160|162|164|166|168|170|172|174|
07407 ; |    11 | Ace                  |176|177|178|179|180|181|182|183|184|185|186|187|188|189|190|191|
07408 ; |    12 | Lieutenant           |192|193|194|195|196|197|198|199|200|201|202|203|204|205|206|207|
07409 ; |    13 | Warrior              |208|209|210|211|212|213|214|215|216|217|218|219|220|221|222|223|
07410 ; |    14 | Captain              |224|225|226|227|228|229|230|231|232|233|234|235|236|237|238|239|
07411 ; |    15 | Commander            |240|242|244|246|248|250|252|254|   |   |   |   |   |   |   |   |
07412 ; |    16 | Commander            |   |   |   |   |   |   |   |   |256|258|260|262|264|266|268|270|
07413 ; |    17 | Star Commander       |272|274|276|278|280|282|284|286|   |   |   |   |   |   |   |   |
07414 ; |    18 | Star Commander       |   |   |   |   |   |   |   |   |288|290|292|294|296|298|300|302|
07415 ; +-------+----------------------+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
07416 ;
07417 ;      NOTE: This subroutine also clears the vertical and horizontal joystick
07418 ;      directions.
07419 ;
07420 ; INPUT
07421 ;
07422 ;   X = Offset to index table BONUSTAB ($BEDD) of mission bonus values. Used
07423 ;       values are:
07424 ;     $00 -> Mission complete
07425 ;     $04 -> Mission was aborted due to zero energy
07426 ;     $08 -> Our starship was destroyed by Zylon fire
07427 ;
07428 ;   Y = Title phrase offset. Used values are:
07429 ;     $3F -> "MISSION COMPLETE"
07430 ;     $31 -> "MISSION ABORTED ZERO ENERGY"
07431 ;     $23 -> "SHIP DESTROYED BY ZYLON FIRE"
07432
07433 ;*** Game over (Mission failed) ************************************************
07434 GAMEOVER        LDA #0                  ;
07435                 STA PL3LIFE             ; PLAYER3 lifetime := 0 game loops
07436                 STA BEEPPRIORITY        ; Mute beeper
07437                 STA TITLEPHR            ; Clear title line
07438                 STA REDALERTLIFE        ; Red alert flash lifetime := 0 game loops
07439                 STA AUDC4               ; Mute audio channel 4
07440                 STA NEWVELOCITY         ; Shut down Engines
07441                 STA SHIELDSCOLOR        ; Set Shields color to {BLACK}
07442                 STA DRAINSHIELDS        ; Switch off Shields
07443                 STA WARPSTATE           ; Disengage hyperwarp
07444                 STA VELOCITYHI          ; Turn off hyperwarp velocity
07445
07446 ;*** Game over (Mission successful) ********************************************
07447 GAMEOVER2       LDA #$FF                ; Enter demo mode
07448                 STA ISDEMOMODE          ;
07449
07450                 STY NEWTITLEPHR         ; Enqueue title phrase
07451
07452 ;*** Calculate total score *****************************************************
07453                 TXA                     ;
07454                 ORA MISSIONLEVEL        ;
07455                 TAX                     ;
07456                 LDA BONUSTAB,X          ; Retrieve mission bonus
07457                 CLC                     ; Add mission bonus and game score
07458                 ADC SCORE               ;
07459                 TAX                     ;
07460                 LDA #0                  ;
07461
07462                 STA JOYSTICKY           ; Clear vertical joystick delta
07463                 STA JOYSTICKX           ; Clear horizontal joystick delta
07464
07465                 ADC SCORE+1             ;
07466                 BMI SKIP165             ; Return if total score < 0 (= total score of 0)
07467
07468 ;*** Calculate scored rank *****************************************************
07469                 LSR A                   ;
07470                 TXA                     ;
07471                 ROR A                   ;
07472                 LSR A                   ;
07473                 LSR A                   ;
07474                 LSR A                   ; Use bits B8..4 of total score as rank index
07475                 CMP #19                 ; Limit scored rank index to 0..18
07476                 BCC SKIP162             ;
07477                 LDA #18                 ;
07478                 LDX #15                 ; Prep class index of 15
07479 SKIP162         STA SCOREDRANKIND       ; Store scored rank index
07480
07481 ;*** Calculate scored class ****************************************************
07482                 TAY                     ;
07483                 TXA                     ;
07484                 CPY #0                  ;
07485                 BEQ SKIP164             ;
07486                 CPY #11                 ;
07487                 BCC SKIP163             ;
07488                 CPY #15                 ;
07489                 BCC SKIP164             ;
07490 SKIP163         LSR A                   ;
07491                 EOR #$08                ;
07492 SKIP164         AND #$0F                ;
07493                 STA SCOREDCLASSIND      ; Store scored class index, is 0..15
07494
07495 SKIP165         RTS                     ; Return
07496
07497 ;*******************************************************************************
07498 ;*                                                                             *
07499 ;*                                 SELECTWARP                                  *
07500 ;*                                                                             *
07501 ;*             Select hyperwarp arrival location on Galactic Chart             *
07502 ;*                                                                             *
07503 ;*******************************************************************************
07504
07505 ; DESCRIPTION
07506 ;
07507 ; This subroutine executes the following steps:
07508 ;
07509 ; (1)  Check if we are in Galactic Chart view and not in hyperwarp.
07510 ;
07511 ; (2)  Update the Galactic Chart in subroutine DRAWGC ($B4B9) if the Subspace
07512 ;      Radio is not damaged.
07513 ;
07514 ; (3)  Move the arrival hyperwarp marker (PLAYER4) across the Galactic Chart
07515 ;      every other game loop iteration. The current location of our starship is
07516 ;      indicated by the departure hyperwarp marker (PLAYER3).
07517 ;
07518 ; Code execution continues into subroutine CALCWARP ($B1A7) to calculate the
07519 ; required hyperwarp energy to hyperwarp from the departure hyperwarp marker
07520 ; position to the arrival hyperwarp marker position.
07521 ;
07522 ; NOTE: To calculate the horizontal position of PLAYER3..4 an offset of 61 is
07523 ; added (from left to right: 48 Player/Missile (PM) pixels to the left edge of
07524 ; the screen + 16 PM pixels to the left border of the Galactic Chart - 3 PM
07525 ; pixels relative offset of the PLAYER shape's horizontal center to its left
07526 ; edge = 61 PM pixels).
07527 ;
07528 ; NOTE: To calculate the vertical position of PLAYER3..4 an offset of 63 is
07529 ; added (from top to bottom: 8 Player/Missile (PM) pixels to the start of the
07530 ; Display List + 56 PM pixels to the first row of sectors - 1 PM pixel relative
07531 ; offset of the PLAYER shape's vertical center to its top edge (?) = 63 PM
07532 ; pixels).
07533
07534 SELECTWARP      LDA WARPSTATE           ; Return if hyperwarp engaged
07535                 BNE SKIP166             ;
07536
07537                 LDA SHIPVIEW            ; Return if not in Galactic Chart view
07538                 BMI SKIP167             ;
07539 SKIP166         RTS                     ; Return
07540
07541 SKIP167         BIT GCSTATRAD           ; Skip if Subspace Radio is damaged or destroyed
07542                 BMI SKIP168             ;
07543
07544                 JSR DRAWGC              ; Redraw Galactic Chart
07545
07546 SKIP168         LDA COUNT8              ; Move hyperwarp markers only every other game loop
07547                 AND #$01                ; (slowing down movement of hyperwarp markers)
07548                 BNE CALCWARP            ;
07549
07550 ;*** Calc arrival hyperwarp marker column and row numbers, update PLAYER4 pos **
07551                 CLC                     ;
07552                 LDA WARPARRVCOLUMN      ; Load arrival hyperwarp marker column number
07553                 ADC JOYSTICKX           ; Add joystick x-delta
07554                 AND #$7F                ; Limit value to 0..127
07555                 STA WARPARRVCOLUMN      ; Save new arrival hyperwarp marker column number
07556                 CLC                     ;
07557                 ADC #61                 ; Add offset of 61
07558                 STA PL4COLUMN           ; Store as PLAYER4 column number
07559
07560                 CLC                     ;
07561                 LDA WARPARRVROW         ; Load arrival hyperwarp marker row number
07562                 ADC JOYSTICKY           ; Add joystick y-delta
07563                 AND #$7F                ; Limit value to 0..127
07564                 STA WARPARRVROW         ; Save new arrival hyperwarp marker row number
07565                 CLC                     ;
07566                 ADC #63                 ; Add offset of 63
07567                 STA PL4ROWNEW           ; Store as PLAYER4 row number
07568
07569 ;*** Calc departure hyperwarp marker column and row numbers, update PLAYER3 pos 
07570                 LDA WARPDEPRROW         ; Load departure hyperwarp marker row number
07571                 CLC                     ;
07572                 ADC #63                 ; Add offset of 63
07573                 STA PL3ROWNEW           ; Store as PLAYER3 row number
07574
07575                 LDA WARPDEPRCOLUMN      ; Load departure hyperwarp marker column number
07576                 CLC                     ;
07577                 ADC #61                 ; Add offset of 61
07578                 STA PL3COLUMN           ; Store as PLAYER3 column number
07579
07580 ;*******************************************************************************
07581 ;*                                                                             *
07582 ;*                                  CALCWARP                                   *
07583 ;*                                                                             *
07584 ;*                   Calculate and display hyperwarp energy                    *
07585 ;*                                                                             *
07586 ;*******************************************************************************
07587
07588 ; DESCRIPTION
07589 ;
07590 ; Calculates and displays the hyperwarp energy in the Galactic Chart view.
07591 ;
07592 ; This subroutine executes the following steps:
07593 ;
07594 ; (1)  Determine the arrival sector from the arrival hyperwarp marker position.
07595 ;
07596 ; (2)  If the Subspace Radio is not destroyed, update the target number digit of
07597 ;      the Galactic Chart Panel Display.
07598 ;
07599 ; (3)  Calculate the hyperwarp energy that is required to hyperwarp from the
07600 ;      departure hyperwarp marker to the arrival hyperwarp marker based on the
07601 ;      "block-distance":
07602 ;
07603 ;          DISTANCE := DELTAR / 2 + DELTAC
07604 ;
07605 ;          where
07606 ;
07607 ;          DELTAR := ABS(WARPARRVROW - WARPDEPRROW)
07608 ;          DELTAC := ABS(WARPARRVCOLUMN - WARPDEPRCOLUMN)
07609 ;
07610 ;      NOTE: Dividing DELTAR by 2 compensates for PLAYERs at single-line
07611 ;      resolution having Player/Missile pixels that are half as high as they are
07612 ;      wide.
07613 ;
07614 ;      The hyperwarp energy, divided by 10, is the sum of a value picked from
07615 ;      the hyperwarp energy table WARPENERGYTAB ($BADD) indexed by DISTANCE / 8)
07616 ;      plus a remainder computed from Bits B1..0 of DISTANCE. 
07617 ;
07618 ; (4)  Store the hyperwarp energy value in WARPENERGY ($91).
07619 ;
07620 ; (5)  Update the HYPERWARP ENERGY readout of the Galactic Chart Panel Display.
07621
07622 L.WARPARRVCOL   = $6A                   ; Saves arrival sector column number
07623 L.DELTAC        = $6A                   ; Saves diff column value
07624
07625 ;*** Calculate arrival sector **************************************************
07626 CALCWARP        LDA WARPARRVCOLUMN      ;
07627                 LSR A                   ;
07628                 LSR A                   ;
07629                 LSR A                   ;
07630                 STA L.WARPARRVCOL       ; A := arrival sector column 0..15
07631                 LDA WARPARRVROW         ;
07632                 AND #$70                ; A := arrival sector row (0..7) * 16
07633                 ORA L.WARPARRVCOL       ;
07634                 STA ARRVSECTOR          ; Save arrival sector (format %0rrrcccc)
07635
07636 ;*** Update target number digit of Galactic Chart Panel Display ****************
07637                 TAX                     ;
07638                 LDA GCMEMMAP,X          ; Get number of Zylon ships in arrival sector
07639                 BPL SKIP169             ; Skip if no starbase in arrival sector
07640                 LDA #0                  ; Clear number of Zylon ships
07641 SKIP169         ORA #CCS.COL2!ROM.0     ; Merge COLOR2 bits with number of Zylon ships
07642                 BIT GCSTATRAD           ; Skip if Subspace Radio destroyed
07643                 BVS SKIP170             ;
07644
07645                 STA GCTRGCNT            ; Set target number digit of Galactic Chart Panel
07646
07647 ;*** Calculate energy to hyperwarp between hyperwarp markers *******************
07648 SKIP170         SEC                     ; A := DELTAC := ABS(WARPARRVCOLUMN - WARPDEPRCOLUMN)
07649                 LDA WARPARRVCOLUMN      ; (Column value difference)
07650                 SBC WARPDEPRCOLUMN      ;
07651                 BCS SKIP171             ;
07652                 EOR #$FF                ;
07653                 ADC #1                  ;
07654 SKIP171         STA L.DELTAC            ;
07655
07656                 SEC                     ; A := DELTAR := ABS(WARPARRVROW - WARPDEPRROW)
07657                 LDA WARPARRVROW         ; (Row value difference)
07658                 SBC WARPDEPRROW         ;
07659                 BCS SKIP172             ;
07660                 EOR #$FF                ;
07661                 ADC #1                  ;
07662
07663 SKIP172         LSR A                   ; A := DISTANCE := DELTAR / 2 + DELTAC
07664                 CLC                     ;
07665                 ADC L.DELTAC            ;
07666
07667                 TAY                     ; Save DISTANCE
07668                 LSR A                   ; Calc index into hyperwarp energy table
07669                 LSR A                   ;
07670                 LSR A                   ;
07671                 TAX                     ;
07672
07673                 TYA                     ; Load DISTANCE value
07674                 AND #$03                ; Get DISTANCE bits B1..0
07675                 CLC                     ;
07676                 ADC WARPENERGYTAB,X     ; Add hyperwarp energy from table
07677                 STA WARPENERGY          ; Save hyperwarp energy
07678
07679 ;*** Update HYPERWARP ENERGY readout of Galactic Chart Panel Display ***********
07680                 TAY                     ; Prep with hyperwarp energy value
07681
07682                 LDA #ROM.0              ; Set HYPERWARP ENERGY readout digit1..3 to '0'
07683                 STA GCWARPD1            ;
07684                 STA GCWARPD1+1          ;
07685                 STA GCWARPD1+2          ;
07686
07687 LOOP053         LDX #2                  ; Loop over HYPERWARP ENERGY readout digit3..1
07688 LOOP054         INC GCWARPD1,X          ; Increment digit value
07689                 LDA GCWARPD1,X          ;
07690                 CMP #ROM.9+1            ;
07691                 BCC SKIP173             ; Skip if energy digit <= '9'
07692
07693                 LDA #ROM.0              ; Replace energy digit with '0'
07694                 STA GCWARPD1,X          ;
07695                 DEX                     ;
07696                 BPL LOOP054             ; Next energy digit
07697
07698 SKIP173         DEY                     ; Decrement HYPERWARP ENERGY readout value
07699                 BNE LOOP053             ;
07700                 RTS                     ; Return
07701
07702 ;*******************************************************************************
07703 ;*                                                                             *
07704 ;*                                  UPDTITLE                                   *
07705 ;*                                                                             *
07706 ;*                              Update title line                              *
07707 ;*                                                                             *
07708 ;*******************************************************************************
07709
07710 ; DESCRIPTION
07711 ;
07712 ; Updates the title phrase displayed in the title line.
07713 ;
07714 ; If no title phrase has been set then fetch the offset of the next ("enqueued")
07715 ; title phrase to be displayed. If one has been set then code execution
07716 ; continues into subroutine SETTITLE ($B223), otherwise code execution returns.
07717 ;
07718 ; If a title phrase has been set then decrement the lifetime of the currently
07719 ; displayed title phrase segment. If its lifetime has reached a value of 0 then
07720 ; branch to subroutine SETTITLE ($B223) to display the next segment.
07721
07722 UPDTITLE        LDA TITLEPHR            ; Skip if no title phrase set
07723                 BEQ SKIP175             ;
07724
07725                 DEC TITLELIFE           ; Decrement title phrase segment lifetime
07726                 BEQ SKIP176             ; If lifetime expired show next title segment
07727
07728 SKIP174         RTS                     ; Return
07729
07730 SKIP175         LDY NEWTITLEPHR         ; Prep enqueued new title phrase
07731                 BEQ SKIP174             ; Return if not set
07732
07733 ;*******************************************************************************
07734 ;*                                                                             *
07735 ;*                                  SETTITLE                                   *
07736 ;*                                                                             *
07737 ;*                       Set title phrase in title line                        *
07738 ;*                                                                             *
07739 ;*******************************************************************************
07740
07741 ; DESCRIPTION
07742 ;
07743 ; Displays a title phrase in the title line. 
07744 ;
07745 ; INTRODUCTION
07746 ;
07747 ; Title phrases are picked from the title phrase table PHRASETAB ($BBAA). They
07748 ; consist of one or more phrase tokens. Each token is a byte representing a word
07749 ; in word table WORDTAB ($BC2B). Two special tokens are placeholders for the
07750 ; scored class string ($FC) and scored rank string ($FD).
07751 ;
07752 ; A title phrase is split up into one or more title phrase segments, each
07753 ; fitting into the title line. One title phrase segment is displayed after the
07754 ; other after a delay called the "title segment lifetime".
07755 ;
07756 ; Phrase tokens, except the tokens for the scored class ($FC) and for the scored
07757 ; rank ($FD), contain the number of a word in word table WORDTAB ($BC2B) and may
07758 ; contain an end-of-segment or end-of-phrase marker bit.
07759 ;
07760 ; DETAILS
07761 ;
07762 ; The Display List is modified by subroutine MODDLST ($ADF1) to display the
07763 ; title line. Then, the title line is cleared and the words of the title phrase
07764 ; are copied into it using the passed offset into title phrase table PHRASETAB
07765 ; ($BBAA). If the offset has a value of $FF the title line is hidden in
07766 ; subroutine MODDLST ($ADF1). 
07767 ;
07768 ; INPUT
07769 ;
07770 ;   Y = Offset into title phrase table PHRASETAB ($BBAA). Used values are:
07771 ;     $FF  -> Hide title line
07772 ;     else -> Offset into title phrase table PHRASETAB ($BBAA), with explicitly
07773 ;             used values:
07774 ;
07775 ;     $01 -> "COMPUTER ON"
07776 ;     $04 -> "COMPUTER OFF"
07777 ;     $07 -> "SHIELDS ON"
07778 ;     $09 -> "SHIELDS OFF"
07779 ;     $0B -> "COMPUTER TRACKING ON"
07780 ;     $0E -> "TRACKING OFF"
07781 ;     $13 -> "STARBASE SURROUNDED"
07782 ;     $15 -> "STARBASE DESTROYED"
07783 ;     $1F -> "DOCKING ABORTED"
07784 ;     $21 -> "TRANSFER COMPLETE"
07785 ;     $4A -> "NOVICE MISSION"
07786 ;     $4C -> "PILOT MISSION"
07787 ;     $4E -> "WARRIOR MISSION"
07788 ;     $50 -> "COMMANDER MISSION"
07789 ;     $52 -> "DAMAGE CONTROL..."
07790 ;     $75 -> "RED ALERT"
07791
07792 L.WORD          = $6A                   ; Saves word number of WORDTAB ($BC2A). Used values
07793                                         ; are $00..$3F.
07794 L.COLUMNPOS     = $6B                   ; Saves cursor column position during copying text
07795                                         ; into title line
07796 L.TOKEN         = $6C                   ; Saves title phrase token from PHRASETAB ($BBAA),
07797                                         ; contains bit-encoded information about one word in
07798                                         ; the title phrase:
07799                                         ; B7..6 = %00 -> Copy next word to title line
07800                                         ; B7..6 = %01 -> End-of-phrase reached, apply short
07801                                         ;                delay, then hide title line. Title
07802                                         ;                segment lifetime = 60 game loops.
07803                                         ; B7..6 = %10 -> End-of-segment reached. Title
07804                                         ;                segment lifetime = 60 game loops
07805                                         ; B7..6 = %11 -> End-of-phrase reached, apply long
07806                                         ;                delay, then hide title line. Title
07807                                         ;                segment lifetime = 254 game loops.
07808                                         ;                Used with title phrases
07809                                         ;                  "STARBASE SURROUNDED"
07810                                         ;                  "STARBASE DESTROYED"
07811                                         ;                  "HYPERSPACE"
07812                                         ;                  "RED ALERT"
07813                                         ; B5..0       -> Word number of WORDTAB ($BC2A)
07814
07815 SETTITLE        STY TITLEPHR            ; Save title phrase offset
07816
07817                 LDY #$23                ; Show title line
07818                 LDX #$0F                ;
07819                 LDA #$07                ;
07820                 JSR MODDLST             ;
07821
07822 ;*** Init cursor column position and clear title line **************************
07823 SKIP176         LDX #19                 ; There are 19(+1) characters to clear
07824                 LDA #0                  ;
07825                 STA L.COLUMNPOS         ; Init cursor column position
07826
07827 LOOP055         STA TITLETXT,X          ; Clear character in title line
07828                 DEX                     ;
07829                 BPL LOOP055             ;
07830
07831 ;*** If title phrase offset = $FF then hide title line *************************
07832 SKIP177         LDX TITLEPHR            ; Load title phrase offset
07833                 INC TITLEPHR            ; Prepare title phrase offset for next word
07834                 BNE SKIP178             ; ...skip if it turned 0
07835
07836                 LDX #$0F                ; Remove title line and return
07837                 LDY #$80                ;
07838                 LDA #$07                ;
07839                 JMP MODDLST             ;
07840
07841 SKIP178         LDA PHRASETAB,X         ; Get phrase token
07842
07843 ;*** Display scored class? *****************************************************
07844                 CMP #$FC                ; Skip if not "scored class" token
07845                 BNE SKIP179             ;
07846
07847                 LDY SCOREDCLASSIND      ; Get scored class index, is in 0..15
07848                 LDA CLASSTAB,Y          ; Load scored class number digit
07849                 LDX L.COLUMNPOS         ; Load cursor position
07850                 STA TITLETXT,X          ; Store class in title line
07851                 LDA #60                 ; Title segment lifetime := 60 game loops
07852                 STA TITLELIFE           ;
07853                 RTS                     ; Return
07854
07855 ;*** Display scored rank? ******************************************************
07856 SKIP179         CMP #$FD                ; Skip if not "scored rank" token
07857                 BNE SKIP180             ;
07858
07859                 LDY SCOREDRANKIND       ; Get scored rank index, is in 0..18
07860                 LDA RANKTAB,Y           ; Load rank word number
07861
07862 ;*** Search word of token in word table ****************************************
07863 SKIP180         STA L.TOKEN             ; Save phrase token
07864                 AND #$3F                ; Strip bits B6..7 from phrase token
07865                 STA L.WORD              ; Store word number (bits B5..0)
07866
07867                 LDA #<[WORDTAB-1]       ; Point MEMPTR to WORDTAB-1
07868                 STA MEMPTR              ;
07869                 LDA #>[WORDTAB-1]       ;
07870                 STA MEMPTR+1            ;
07871
07872 LOOP056         INC MEMPTR              ; Increment MEMPTR
07873                 BNE SKIP181             ;
07874                 INC MEMPTR+1            ;
07875
07876 SKIP181         LDY #0                  ;
07877                 LDA (MEMPTR),Y          ; Load character of word
07878                 BPL LOOP056             ; Loop until end-of-word marker (bit B7) found
07879                 DEC L.WORD              ;
07880                 BNE LOOP056             ; Loop until word found
07881
07882 ;*** Copy word to title line, add space ****************************************
07883 LOOP057         AND #$3F                ; Strip color bits B6..7 from character
07884                 EOR #CCS.COL2!$20       ; Merge COLOR2 bits and convert to ATASCII
07885                 LDX L.COLUMNPOS         ; Copy character to title line
07886                 INC L.COLUMNPOS         ; Increment cursor column position
07887                 STA TITLETXT,X          ;
07888                 INY                     ;
07889                 LDA (MEMPTR),Y          ; Load next character of word
07890                 BPL LOOP057             ; Next character of word if no end-of-word marker
07891                 INC L.COLUMNPOS         ; Word was copied. Add space after word.
07892
07893 ;*** Decide to copy another word, etc. *****************************************
07894                 LDA #60                 ; SUMMARY:
07895                 BIT L.TOKEN             ; If bits B7..6 of phrase token...
07896                 BPL SKIP182             ; %00 -> Copy next word to title line
07897                 BVC SKIP183             ; %01 -> End-of-phrase, short delay, hide title line
07898                 LDA #254                ;        Title segment lifetime := 60 game loops
07899 SKIP182         BVC SKIP177             ; %10 -> End-of-segment.
07900                 LDY #$FF                ;        Title segment lifetime := 60 game loops
07901                 STY TITLEPHR            ; %11 -> End-of-phrase, long delay, hide title line
07902 SKIP183         STA TITLELIFE           ;        Title segment lifetime := 254 game loops
07903                 RTS                     ; Return
07904
07905 ;*******************************************************************************
07906 ;*                                                                             *
07907 ;*                                    SOUND                                    *
07908 ;*                                                                             *
07909 ;*                            Handle sound effects                             *
07910 ;*                                                                             *
07911 ;*******************************************************************************
07912
07913 ; DESCRIPTION
07914 ;
07915 ; This subroutine handles the sound effects. It is called every vertical blank
07916 ; phase, that is, every TICK (1/60 s on an NTSC Atari 8-bit Home Computer
07917 ; system, 1/50 s on a PAL Atari 8-bit Home Computer system) from the Vertical
07918 ; Blank Interrupt handler VBIHNDLR ($A6D1).
07919 ;
07920 ; The game uses all of the available 4 audio channels: Audio channels 1, 2, and
07921 ; 3 are shared among the Engines sound effects and the "noise sound patterns"
07922 ; (explosion and photon torpedo sound effects), while audio channel 4 is used
07923 ; for "beeper sound patterns" (status report sound effects). The following
07924 ; sections explain the beeper sound patterns and the noise sound patterns:
07925 ;
07926 ; o   BEEPER SOUND PATTERNS
07927 ;
07928 ;     There are the following beeper sound patterns:
07929 ;
07930 ;     (1)  HYPERWARP TRANSIT
07931 ;     (2)  RED ALERT
07932 ;     (3)  ACKNOWLEDGE
07933 ;     (4)  DAMAGE REPORT
07934 ;     (5)  MESSAGE FROM STARBASE
07935 ;
07936 ;     They are encoded in table BEEPPATTAB ($BF3E) in 6-byte long "beeper sound
07937 ;     patterns". 
07938 ;
07939 ;     Another table, BEEPFRQTAB ($BF5C), stores the frequencies for the tones
07940 ;     of each beeper sound pattern, terminated by a marker byte ($FF).
07941 ;
07942 ;     BUG (at $BF5C): The pattern frequencies in table BEEPFRQTAB ($BF5C) at
07943 ;     offset $00 are unused. Suggested Fix: Remove from code.
07944 ;
07945 ;     Whenever the game calls subroutine BEEP ($B3A6), that subroutine sets up a
07946 ;     beeper sound pattern for playing by copying 6 bytes from the pattern table
07947 ;     BEEPPATTAB ($BF3E) to BEEPFRQIND ($D2)..BEEPFRQSTART ($D7). Subroutine
07948 ;     SOUND ($B2AB) detects the copied beeper sound pattern and plays the
07949 ;     encoded tones and pauses.
07950 ;
07951 ;     The relevant variables for playing a beeper sound pattern are the
07952 ;     following (see also figures at BEEPPATTAB ($BF3E)):
07953 ;
07954 ;     BEEPFRQIND    ($D2)   = Running index into table BEEPFRQTAB ($BF5C)
07955 ;     BEEPREPEAT    ($D3)   = Number of times that the beeper sound pattern is
07956 ;                             repeated - 1
07957 ;     BEEPTONELIFE  ($D4)   = Lifetime of tone in TICKs - 1
07958 ;     BEEPPAUSELIFE ($D5)   = Lifetime of pause in TICKs - 1 ($FF -> No pause)
07959 ;     BEEPPRIORITY  ($D6)   = Beeper sound pattern priority. A playing beeper
07960 ;                             sound pattern is stopped if a beeper sound pattern
07961 ;                             of higher priority is about to be played. A value
07962 ;                             of 0 indicates that no beeper sound pattern is
07963 ;                             playing at the moment.
07964 ;     BEEPFRQSTART  ($D7)   = Index to first byte of the beeper sound pattern in
07965 ;                             table BEEPFRQTAB ($BF5C)
07966 ;
07967 ;     BEEPLIFE      ($D8)   = Lifetime of the current tone or pause in TICKs
07968 ;     BEEPTOGGLE    ($D9)   = Indicates that either a tone (0) or a pause (not
07969 ;                             0) is currently playing.
07970 ;
07971 ; o   NOISE SOUND PATTERNS
07972 ;
07973 ;     There are the following noise sound patterns:
07974 ;
07975 ;     (1)  PHOTON TORPEDO LAUNCHED
07976 ;     (2)  SHIELD EXPLOSION
07977 ;     (3)  ZYLON EXPLOSION
07978 ;
07979 ;     They are encoded in table NOISEPATTAB ($BF20) in 10-byte long "noise sound
07980 ;     patterns". 
07981 ;
07982 ;     Whenever the game calls subroutine NOISE ($AEA8), that subroutine sets up
07983 ;     a noise sound pattern for being played by copying 10 bytes from the
07984 ;     pattern table NOISEPATTAB ($BF20) to NOISETORPTIM ($DA)..NOISELIFE ($E1)
07985 ;     and hardware sound registers AUDCTL ($D208) and AUDF3 ($D204).
07986 ;
07987 ;     The relevant variables for playing a noise sound pattern are the
07988 ;     following:
07989 ;
07990 ;     NOISETORPTIM  ($DA)   = Delay timer for PHOTON TORPEDO LAUNCHED noise
07991 ;                             sound pattern
07992 ;     NOISEEXPLTIM  ($DB)   = Delay timer for SHIELD EXPLOSION and ZYLON
07993 ;                             EXPLOSION noise sound patterns
07994 ;     NOISEAUDC2    ($DC)   = Audio channel 1/2 control shadow register
07995 ;     NOISEAUDC3    ($DD)   = Audio channel 3   control shadow register
07996 ;     NOISEAUDF1    ($DE)   = Audio channel 1 frequency shadow register
07997 ;     NOISEAUDF2    ($DF)   = Audio channel 2 frequency shadow register
07998 ;     NOISEFRQINC   ($E0)   = Audio channel 1/2 frequency increment
07999 ;     NOISELIFE     ($E1)   = Noise sound pattern lifetime
08000 ;
08001 ;     AUDCTL        ($D208) = POKEY: Audio control
08002 ;     AUDF3         ($D204) = POKEY: Audio channel 3 frequency audio register
08003 ;
08004 ;     There are two more variables that trigger noise effects. They are not part
08005 ;     of the noise sound pattern table:
08006 ;
08007 ;     NOISEZYLONTIM ($E2)   = Delay timer to trigger the ZYLON EXPLOSION noise
08008 ;                             sound pattern. It is set in subroutine COLLISION
08009 ;                             ($AF3D) when the impact of one of our starship's
08010 ;                             photon torpedoes with a target is imminent. The
08011 ;                             timer is decremented every TICK. When it reaches a
08012 ;                             value of 0 the ZYLON EXPLOSION noise sound pattern
08013 ;                             is played in subroutine SOUND ($B2AB). 
08014 ;     NOISEHITLIFE ($E3)    = Lifetime of the STARSHIP EXPLOSION noise when our
08015 ;                             starship was destroyed by a Zylon photon torpedo.
08016 ;                             It is set in GAMELOOP ($A1F3) to a value of 64
08017 ;                             TICKs. When it reaches a value of 0 the STARSHIP
08018 ;                             EXPLOSION noise is played in subroutine SOUND
08019 ;                             ($B2AB).
08020 ;
08021 ; SUBROUTINE DETAILS
08022 ;
08023 ; This subroutine executes the following steps:
08024 ;
08025 ; (1)  Play beeper sound pattern
08026 ;
08027 ;      The playing of a beeper sound pattern is started, continued, or stopped.
08028 ;
08029 ; (2)  Play ZYLON EXPLOSION noise sound pattern
08030 ;
08031 ;      If the explosion of a target space object is imminent (subroutine
08032 ;      COLLISION ($AF3D) has set NOISEZYLONTIM ($E2) to the number of game loop
08033 ;      iterations that will pass until our starship's photon torpedo will hit
08034 ;      the target), the timer NOISEZYLONTIM ($E2) is decremented every TICK. If
08035 ;      it reaches a value of 0, then the noise sound pattern ZYLON EXPLOSION is
08036 ;      played.
08037 ;
08038 ; (3)  Play starship's Engines sound
08039 ;
08040 ;      If the Engines are louder than the current noise sound pattern then the
08041 ;      noise sound pattern is terminated and the values for the audio channels
08042 ;      1..3 are updated: 
08043 ;
08044 ;      The velocity of our starship determines the pitch and the volume of the
08045 ;      Engines: the higher the velocity, the higher the pitch and the volume of
08046 ;      the Engines. The incremented value of VELOCITYLO ($70) is used as a "base
08047 ;      value" %abcdefgh.
08048 ;
08049 ;      Audio channels 1 and 2 are combined to a 16-bit audio channel 1/2,
08050 ;      clocked at 1.79 MHz. The inverted bits (represented by an overscore)
08051 ;      B7..0 of the base value form bits B12..5 of the 16-bit frequency value of
08052 ;      audio channel 1/2. Bits B7..4 of the base value form bits B3..0 of the
08053 ;      volume of audio channel 1/2, with noise distortion bit B7 set:
08054 ;                               ________
08055 ;      AUDF1/2 ($D202..3) := %000abcdefgh00000
08056 ;      AUDC2   ($D203)    := %1000abcd
08057 ;
08058 ;      Audio channel 3 is also clocked at 1.79 MHz. The inverted bits B7..0 of
08059 ;      the base value form bits B7..0 of the frequency value of audio channel 3.
08060 ;      Bits B6..4 of the base value form bits B3..0 of the volume of audio
08061 ;      channel 3, with noise distortion bit B7 set:
08062 ;                            ________
08063 ;      AUDF3   ($D204)    := %abcdefgh
08064 ;      AUDC3   ($D205)    := %10000bcd
08065 ;
08066 ;      Code execution returns at this point.
08067 ;
08068 ; (4)  Play ZYLON EXPLOSION or SHIELD EXPLOSION noise sound pattern
08069 ;
08070 ;      If the ZYLON EXPLOSION or SHIELD EXPLOSION noise sound pattern was set
08071 ;      up, the explosion noise timer NOISEEXPLTIM ($DB) is decremented every
08072 ;      TICK. It starts either with a value of 4 TICKs with a ZYLON EXPLOSION
08073 ;      noise sound pattern or with a value of 8 TICKs with a SHIELD EXPLOSION
08074 ;      noise sound pattern, set up in subroutine NOISE ($AEA8). If it reaches a
08075 ;      value of 0, then the shadow control register of audio channel 1/2
08076 ;      switches to "noise distortion" at maximum volume.
08077 ;
08078 ; (5)  Play PHOTON TORPEDO LAUNCHED noise sound pattern
08079 ;
08080 ;      If the PHOTON TORPEDO LAUNCHED noise sound pattern was set up, the photon
08081 ;      torpedo noise timer NOISETORPTIM ($DA) is decremented every TICK. It
08082 ;      starts with a value of 8 TICKs, set in subroutine TRIGGER ($AE29). The
08083 ;      noise distortion and volume for the shadow control register of audio
08084 ;      channel 3 is picked from table NOISETORPVOLTAB ($BFEB), the noise
08085 ;      frequency for audio channel 3 is picked from table NOISETORPFRQTAB
08086 ;      ($BFF3). If the photon torpedo noise timer reaches a value of 0, then the
08087 ;      shadow control registers of audio channel 1/2 switch to "tone distortion"
08088 ;      at maximum volume and a frequency of $0202.
08089 ;
08090 ;      NOTE: Using a real-time volume envelope stored in table NOISETORPVOLTAB
08091 ;      ($BFEB) for a launched photon torpedo results in producing the
08092 ;      distinctive "whooshing" photon torpedo sound.
08093 ;
08094 ; (6)  Play STARSHIP EXPLOSION noise
08095 ;
08096 ;      If our starship was hit by a Zylon photon torpedo then NOISEHITLIFE ($E3)
08097 ;      was set to 64 TICKs in routine GAMELOOP ($A1F3). While this value is
08098 ;      decremented every TICK, a random frequency value is stored to audio
08099 ;      channel 3 and the distortion bit of the shadow control register of audio
08100 ;      channel 3 is randomly toggled.
08101 ;
08102 ; (7)  Increase audio channels 1/2 frequency
08103 ;
08104 ;      The 16-bit frequency value of audio channels 1/2 (both shadow registers
08105 ;      and audio registers) is increased every TICK by an increment picked from
08106 ;      the currently playing noise sound pattern.
08107 ;
08108 ; (8)  Mute audio channels gradually
08109 ;
08110 ;      Toward the end of a noise sound pattern's lifetime all audio channels
08111 ;      gradually mute their volume every other TICK until completely silent. 
08112
08113 ;*** Play beeper sound pattern *************************************************
08114 SOUND           LDA BEEPPRIORITY        ; Skip if beeper sound pattern not in use
08115                 BEQ SKIP185             ;
08116
08117                 DEC BEEPLIFE            ; Decrement beeper lifetime
08118                 BPL SKIP185             ; Skip if beeper lifetime still counting down
08119
08120                 LDA BEEPTOGGLE          ; Load tone/pause toggle
08121                 BEQ LOOP058             ; Skip if a tone is playing or is to be played
08122
08123                 LDA BEEPPAUSELIFE       ; Load pause lifetime
08124                 BMI LOOP058             ; Skip if duration = $FF (no pause)
08125                 STA BEEPLIFE            ; Store pause lifetime as beeper lifetime
08126                 LDY #0                  ; Prep AUDC4 (zero volume)
08127                 BEQ SKIP184             ; Skip unconditionally
08128
08129 LOOP058         LDA BEEPTONELIFE        ; Load tone lifetime
08130                 STA BEEPLIFE            ; Store tone lifetime as beeper lifetime
08131                 LDX BEEPFRQIND          ; Load frequency index
08132                 INC BEEPFRQIND          ; Increment frequency index
08133                 LDA BEEPFRQTAB,X        ; Store tone frequency from frequency table in AUDF4
08134                 STA AUDF4               ;
08135                 LDY #$A8                ; Prep AUDC4 (tone distortion + medium volume)
08136                 CMP #$FF                ; Skip if frequency not $FF (there are more tones)
08137                 BNE SKIP184             ;
08138
08139                 LDA BEEPFRQSTART        ; Rewind pattern frequency pointer
08140                 STA BEEPFRQIND          ;
08141                 DEC BEEPREPEAT          ; Decrement sequence counter
08142                 BPL LOOP058             ; Keep playing until sequence counter < 0
08143
08144                 LDY #0                  ; Prep AUDC4 with zero volume
08145                 STY BEEPPRIORITY        ; Stop playing beeper sound pattern
08146
08147 SKIP184         STY AUDC4               ; Store in AUDC4
08148                 STY BEEPTOGGLE          ; Store in BEEPTOGGLE
08149
08150 ;*** Play ZYLON EXPLOSION noise sound pattern **********************************
08151 SKIP185         LDA NOISEZYLONTIM       ; Skip if ZYLON EXPLOSION timer not in use
08152                 BEQ SKIP186             ;
08153
08154                 DEC NOISEZYLONTIM       ; Decrement ZYLON EXPLOSION timer
08155                 BNE SKIP186             ; Skip if ZYLON EXPLOSION timer still counting down
08156
08157                 LDX #$14                ; Play noise sound pattern ZYLON EXPLOSION
08158                 JSR NOISE               ;
08159
08160 ;*** Play our starship's Engines sound *****************************************
08161 SKIP186         LDX VELOCITYLO          ; Skip if Engines softer than noise sound pattern
08162                 TXA                     ;
08163                 LSR A                   ;
08164                 LSR A                   ;
08165                 LSR A                   ;
08166                 LSR A                   ;
08167                 LSR A                   ;
08168                 CMP NOISELIFE           ;
08169                 BCC SKIP187             ;
08170
08171                 LDA #0                  ; Terminate noise sound pattern
08172                 STA NOISELIFE           ;
08173
08174                 INX                     ;
08175                 TXA                     ; A := %abcdefgh = VELOCITYLO + 1
08176                 EOR #$FF                ;           ________
08177                 STA AUDF3               ; AUDF3 := %abcdefgh
08178
08179                 TAX                     ;                ________
08180                 ASL A                   ; AUDF2/1 := %000abcdefgh00000
08181                 ASL A                   ;
08182                 ASL A                   ;
08183                 ASL A                   ;
08184                 ASL A                   ;
08185                 STA AUDF1               ;
08186                 TXA                     ;
08187                 LSR A                   ;
08188                 LSR A                   ;
08189                 LSR A                   ;
08190                 STA AUDF2               ;
08191
08192                 LSR A                   ; AUDC2 := %1000abcd
08193                 EOR #$8F                ; (noise distortion + B7..B4 bits for volume)
08194                 STA AUDC2               ;
08195
08196                 AND #$87                ; AUDC3 := %10000bcd
08197                 STA AUDC3               ; (noise distortion + B6..B4 bits for volume)
08198
08199                 LDA #$70                ; Clock audio channel 1 and 3 @ 1.79 MHz and...
08200                 STA AUDCTL              ; ...combine audio channel 1/2 to 16-bit channel
08201
08202                 RTS                     ; Return
08203
08204 ;*** Play ZYLON EXPLOSION or SHIELD EXPLOSION noise ****************************
08205 SKIP187         LDA NOISEEXPLTIM        ; Skip if explosion noise timer not in use
08206                 BEQ SKIP188             ;
08207
08208                 DEC NOISEEXPLTIM        ; Decrement explosion noise timer (4 or 8 TICKs long)
08209                 BNE SKIP188             ; Skip if explosion noise timer still counting down
08210
08211                 LDA #$8F                ; Shadow register AUDC2 := (noise dist. + max volume)
08212                 STA NOISEAUDC2          ;
08213
08214 ;*** Play PHOTON TORPEDO LAUNCHED noise sound **********************************
08215 SKIP188         LDX NOISETORPTIM        ; Skip if photon torpedo noise timer not in use
08216                 BEQ SKIP190             ;
08217
08218                 DEC NOISETORPTIM        ; Decrement photon torpedo noise timer (8 TICKs long)
08219                 BNE SKIP189             ; Skip if torpedo noise timer still counting down
08220
08221                 LDA #$AF                ; Shadow register AUDC2 := (tone dist. + max volume)
08222                 STA NOISEAUDC2          ;
08223                 LDA #$02                ; Set frequency $0202 to AUDF1/2's shadow...
08224                 STA NOISEAUDF1          ; ...registers
08225                 STA NOISEAUDF2          ;
08226
08227 SKIP189         LDA NOISETORPVOLTAB-1,X ; Pick torpedo noise + volume shape (X in 1..8)...
08228                 STA NOISEAUDC3          ; ...and store it in AUDC3's shadow register
08229                 LDA NOISETORPFRQTAB-1,X ; Pick photon torpedo noise frequency (X in 1..8)...
08230                 STA AUDF3               ; ...and store it in AUDF3
08231                 STA STIMER              ; Reset POKEY audio timers
08232
08233 ;*** Play STARSHIP EXPLOSION noise when our starship is hit ********************
08234 SKIP190         LDA NOISEHITLIFE        ; Skip if STARSHIP EXPLOSION noise not in use
08235                 BEQ SKIP191             ;
08236
08237                 DEC NOISEHITLIFE        ; Decrement STARSHIP EXPLOSION noise lifetime
08238                 LDA RANDOM              ; Set random frequency to AUDF3
08239                 STA AUDF3               ;
08240                 AND #$20                ; Toggle noise/tone dist. of AUDC3's shadow register
08241                 EOR NOISEAUDC3          ; ...randomly
08242                 STA NOISEAUDC3          ;
08243
08244 ;*** Increase 16-bit frequency of audio channels 1/2 (shadow registers also) ***
08245 SKIP191         CLC                     ; Increase 16-bit frequency value of AUDF1/2...
08246                 LDA NOISEAUDF1          ; ...and its shadow register by...
08247                 ADC NOISEFRQINC         ; ...noise sound pattern frequency increment
08248                 STA NOISEAUDF1          ; AUDF1/2 := NOISEAUDF1/2 := ...
08249                 STA AUDF1               ; ...NOISEAUDF1/2 + NOISEFRQINC
08250                 LDA NOISEAUDF2          ;
08251                 ADC #0                  ;
08252                 STA NOISEAUDF2          ;
08253                 STA AUDF2               ;
08254
08255 ;*** Gradually mute audio channels while noise sound pattern expires ***********
08256                 LDX NOISEAUDC2          ; Prep AUDC2's shadow register value
08257                 LDY NOISEAUDC3          ; Prep AUDC3's shadow register value
08258
08259                 LDA COUNT8              ; Decrement volumes every other TICK
08260                 LSR A                   ;
08261                 BCC SKIP193             ;
08262
08263                 LDA NOISELIFE           ; Skip if noise sound pattern not in use
08264                 BEQ SKIP193             ;
08265
08266                 DEC NOISELIFE           ; Decrement noise sound pattern lifetime
08267
08268                 CMP #17                 ; Mute noise sound pattern only in...
08269                 BCS SKIP193             ; ...the last 16 TICKs of its lifetime
08270
08271                 TXA                     ; Decrement volume of AUDC2's shadow register
08272                 AND #$0F                ;
08273                 BEQ SKIP192             ;
08274                 DEX                     ;
08275                 STX NOISEAUDC2          ;
08276
08277 SKIP192         TYA                     ; Decrement volume of AUDC3's shadow register
08278                 AND #$0F                ;
08279                 BEQ SKIP193             ;
08280                 DEY                     ;
08281                 STY NOISEAUDC3          ;
08282
08283 SKIP193         STX AUDC2               ; Store shadow register values to audio registers
08284                 STY AUDC3               ;
08285
08286                 RTS                     ; Return
08287
08288 ;*******************************************************************************
08289 ;*                                                                             *
08290 ;*                                    BEEP                                     *
08291 ;*                                                                             *
08292 ;*                          Copy beeper sound pattern                          *
08293 ;*                                                                             *
08294 ;*******************************************************************************
08295
08296 ; DESCRIPTION
08297 ;
08298 ; Copies a 6-byte beeper sound pattern from beeper sound pattern table
08299 ; BEEPPATTAB ($BF3E) to BEEPFRQIND ($D2)..BEEPFRQSTART ($D7), provided that no
08300 ; beeper sound pattern with higher priority is currently playing. The beeper
08301 ; sound pattern will then be automatically played in subroutine SOUND ($B2AB).
08302 ; See subroutine SOUND ($B2AB) for more information on beeper sound patterns. 
08303 ;
08304 ; NOTE: The bytes from table BEEPPATTAB ($BF3E) are copied in reverse order.
08305 ;
08306 ; INPUT
08307 ;
08308 ;   X = Offset to beeper sound pattern in table BEEPPATTAB ($BF3E). Used values
08309 ;       are:
08310 ;     $00 -> HYPERWARP TRANSIT
08311 ;     $06 -> RED ALERT
08312 ;     $0C -> ACKNOWLEDGE
08313 ;     $12 -> DAMAGE REPORT
08314 ;     $18 -> MESSAGE FROM STARBASE
08315
08316 BEEP            LDA BEEPPATTAB,X        ; Return if beeper sound pattern of...
08317                 CMP BEEPPRIORITY        ; ...higher priority is playing
08318                 BCC SKIP194             ;
08319
08320                 LDY #5                  ; Copy 6-byte beeper sound pattern (in reverse order)
08321 LOOP059         LDA BEEPPATTAB,X        ;
08322                 STA BEEPFRQIND,Y        ;
08323                 INX                     ;
08324                 DEY                     ;
08325                 BPL LOOP059             ;
08326
08327 SKIP194         RTS                     ; Return
08328
08329 ;*******************************************************************************
08330 ;*                                                                             *
08331 ;*                                 INITIALIZE                                  *
08332 ;*                                                                             *
08333 ;*                          More game initialization                           *
08334 ;*                                                                             *
08335 ;*******************************************************************************
08336
08337 ; DESCRIPTION
08338 ;
08339 ; This subroutine executes the following initialization steps:
08340 ;
08341 ; (1)  Set up Display List
08342 ;
08343 ;      A Display List is created at DSPLST ($0280). It starts with 2 x 8 = 16
08344 ;      blank video lines, followed by 90 GRAPHICS7 rows. After a deliberate gap
08345 ;      in Display List instructions, which will be filled dynamically during the
08346 ;      game by calls to subroutine MODDLST ($ADF1), it ends with a Display List
08347 ;      wait-and-jump-back instruction to the start of the Display List at DSPLST
08348 ;      ($0280).
08349 ;
08350 ;      NOTE: The PLAYFIELD color table PFCOLORTAB ($BFA9) is copied to zero page
08351 ;      table PF0COLOR ($F2) by loop jamming.
08352 ;
08353 ; (2)  Create lookup tables
08354 ;
08355 ;      The first lookup table MAPTO80 ($0DE9) maps a byte value of 0..255 to
08356 ;      0..80. This table is used to map unsigned (absolute) position vector
08357 ;      components (coordinates) to pixel (or PLAYER) row and column numbers.
08358 ;
08359 ;      NOTE: The PLAYFIELD is 160 pixels wide. Pixel column numbers relative the
08360 ;      horizontal PLAYFIELD center are in -80..79, hence the range of this
08361 ;      lookup table. Pixel row numbers relative the vertical PLAYFIELD center
08362 ;      are in -50..49, thus they also fit in the range of this lookup table.
08363 ;
08364 ;      The second lookup table MAPTOBCD99 ($0EE9) maps a byte value of 0..255 to
08365 ;      a BCD-encoded value in 00..99. This table is used to convert byte values
08366 ;      into decimal 2-digit values displayed by the THETA (in "gradons"), PHI
08367 ;      (in "gradons"), RANGE (in "centrons"), and VELOCITY (in "metrons per
08368 ;      second") readouts of the Console Panel Display.
08369 ;
08370 ;      The third and fourth lookup tables accelerate drawing of PLAYFIELD space
08371 ;      objects: In combination they contain the 16-bit start addresses of each
08372 ;      of the 100 rows of PLAYFIELD memory. The low bytes of the 16-bit
08373 ;      addresses are stored in table PFMEMROWLO ($0800). The high bytes are
08374 ;      stored in table PFMEMROWHI ($0864).
08375 ;
08376 ;      NOTE: The address increment is 40 (40 bytes = 160 pixels in GRAPHICS7
08377 ;      mode = 1 PLAYFIELD row of pixels). 
08378 ;
08379 ;      NOTE: The PLAYFIELD consists of 90 GRAPHICS7 rows when the Control Panel
08380 ;      Display is displayed at the bottom. When the Control Panel Display is not
08381 ;      displayed, for example in demo mode, the PLAYFIELD contains additional
08382 ;      GRAPHICS7 rows.  
08383 ;
08384 ; (3)  Copy Control Panel Display and Galactic Chart Panel Display texts
08385 ;
08386 ;      The texts of the Control Panel Display and the Galactic Chart Panel
08387 ;      Display are copied to their respective locations in memory by loop
08388 ;      jamming.
08389 ;
08390 ; (4)  Initialize Zylon unit movement timer
08391 ;
08392 ;      The timer that triggers the movement of Zylon units in the Galactic Chart
08393 ;      is initialized to a value of 99. See subroutine FLUSHGAMELOOP ($B4E4) for
08394 ;      more information on Zylon unit movement.
08395 ;
08396 ; (5)  Create Galactic Chart
08397 ;
08398 ;      The Galactic Chart memory map GCMEMMAP ($08C9) is initialized. It
08399 ;      represents 16 columns x 8 rows of sectors. Each sector contains one of
08400 ;      the 4 sector types stored in table SECTORTYPETAB ($BBA6) (starbase, 4
08401 ;      Zylon ships, 3 Zylon ships, and 2 or 1 Zylon ships), and empty sectors.
08402 ;      Before distributing the sector types, the initial position of our
08403 ;      starship is blocked on the Galactic Chart at sector row 4, sector column
08404 ;      8, so that it will not be inadvertently occupied while other sector types
08405 ;      are distributed. The number of each of the sector types to be distributed
08406 ;      is the mission level plus 2. While Zylon units can be placed anywhere,
08407 ;      starbases are placed neither at the borders of the Galactic Chart nor in
08408 ;      a sector adjacent to an occupied sector. 
08409 ;
08410 ;      After having initialized the Galactic Chart memory map, the top border of
08411 ;      the Galactic Chart is drawn with characters from the custom character
08412 ;      set.
08413 ;
08414 ;      Finally, the sector in which our starship is located and the arrival and
08415 ;      departure hyperwarp marker column and row numbers are initialized.
08416 ;
08417 ; (6)  Apply a final tweak
08418 ;
08419 ;      The last entry of lookup table MAPTOBCD99 ($0EE9) is tweaked to a value
08420 ;      of CCS.INF * 16 + CCS.SPC. It is used to display an infinity symbol by
08421 ;      the RANGE readout of the Control Panel Display in subroutine SHOWCOORD
08422 ;      ($B8A7).
08423 ;
08424 ; Code execution continues into subroutine DRAWGC ($B4B9), which draws the
08425 ; content of the Galactic Chart with characters from the custom character set.
08426
08427 L.MEMPTR1       = $68                   ; 16-bit memory pointer
08428 L.MEMPTR2       = $6A                   ; 16-bit memory pointer
08429 L.SECTORTYPE    = $6A                   ; Saves sector type. Used values are:
08430                                         ;   $CF -> Sector contains starbase
08431                                         ;   $04 -> Sector contains 4 Zylon ships
08432                                         ;   $03 -> Sector contains 3 Zylon ships
08433                                         ;   $02 -> Sector contains 2 or 1 Zylon ships
08434 L.SECTORCNT     = $6B                   ; Saves number of sectors of the current sector type
08435
08436 ;*** Initialize Display List and copy color table ******************************
08437 INITIALIZE      LDX #89                 ; Set 89(+1) GRAPHICS7 rows from DSPLST+5 on
08438 LOOP060         LDA #$0D                ; Prep DL instruction $0D (one row of GRAPHICS7)
08439                 STA DSPLST+5,X          ; DSPLST+5,X := one row of GRAPHICS7
08440                 CPX #10                 ;
08441                 BCS SKIP195             ;
08442                 LDA PFCOLORTAB,X        ; Copy PLAYFIELD color table to zero page table
08443                 STA PF0COLOR,X          ; (loop jamming)
08444 SKIP195         DEX                     ;
08445                 BPL LOOP060             ;
08446
08447                 LDA #$70                ; DSPLST     := BLK8
08448                 STA DSPLST              ; DSPLST+1   := BLK8
08449                 STA DSPLST+1            ;
08450                 LDA #$41                ; DSPLST+103 := WAITJMP @ DSPLST
08451                 STA DSPLST+103          ;
08452                 LDA #<DSPLST            ;
08453                 STA DSPLST+104          ;
08454                 LDA #>DSPLST            ;
08455                 STA DSPLST+105          ;
08456
08457 ;*** Calculate lookup tables ***************************************************
08458                 LDX #0                  ; Clear both 16-bit memory pointers
08459                 STX L.MEMPTR1           ;
08460                 STX L.MEMPTR1+1         ;
08461                 STX L.MEMPTR2           ;
08462                 STX L.MEMPTR2+1         ;
08463
08464 ;*** Calc MAPTO80 map (converts value of $00..$FF to value in 0..80) ***********
08465 LOOP061         CLC                     ;
08466                 LDA L.MEMPTR1           ;
08467                 ADC #81                 ;
08468                 STA L.MEMPTR1           ;
08469                 LDA L.MEMPTR1+1         ;
08470                 STA MAPTO80,X           ;
08471                 ADC #0                  ;
08472                 STA L.MEMPTR1+1         ;
08473
08474 ;*** Calc MAPTOBCD99 map (converts value of $00..$FF to BCD-value in 00..99) ***
08475                 CLC                     ;
08476                 LDA L.MEMPTR2           ;
08477                 ADC #100                ;
08478                 STA L.MEMPTR2           ;
08479                 LDA L.MEMPTR2+1         ;
08480                 STA MAPTOBCD99,X        ;
08481                 SED                     ;
08482                 ADC #0                  ;
08483                 CLD                     ;
08484                 STA L.MEMPTR2+1         ;
08485                 INX                     ;
08486                 BNE LOOP061             ;
08487
08488 ;*** Calculate PLAYFIELD memory row addresses, copy Panel Display texts ********
08489                 LDX #<PFMEM             ; Point L.MEMPTR1 to start of PLAYFIELD memory
08490                 STX L.MEMPTR1           ; (X = 0, because PFMEM is at $1000)
08491                 LDA #>PFMEM             ;
08492                 STA L.MEMPTR1+1         ;
08493
08494 LOOP062         CLC                     ;
08495                 LDA L.MEMPTR1           ;
08496                 STA PFMEMROWLO,X        ; Store 16-bit value of L.MEMPTR1 in PFMEMROWHI/LO
08497                 ADC #40                 ; Add 40 to L.MEMPTR
08498                 STA L.MEMPTR1           ; (40 bytes = 160 pixels = 1 PLAYFIELD row)
08499                 LDA L.MEMPTR1+1         ;
08500                 STA PFMEMROWHI,X        ;
08501                 ADC #0                  ;
08502                 STA L.MEMPTR1+1         ;
08503
08504                 LDA PANELTXTTAB,X       ; Copy Control and Galactic Chart Panel Display texts
08505                 STA PANELTXT,X          ; (loop jamming)
08506
08507                 INX                     ;
08508                 CPX #100                ;
08509                 BCC LOOP062             ; Loop 100 times
08510
08511 ;*** Set Zylon unit movement timer *********************************************
08512                 DEX                     ;
08513                 STX ZYLONUNITTIM        ; Init Zylon unit movement timer to 99 game loops
08514
08515 ;*** Create memory map of the Galactic Chart ***********************************
08516                 LDX #3                  ; Loop over all 3(+1) sector types
08517                 STX GCMEMMAP+4*16+8     ; Block our starship's initial position at center of
08518                                         ; ...Galactic Chart (sector row 4, sector column 8)
08519
08520 LOOP063         LDA SECTORTYPETAB,X     ; Prep sector type
08521                 STA L.SECTORTYPE        ;
08522
08523                 LDY MISSIONLEVEL        ; Number sectors of current type := mission level + 2
08524                 INY                     ;
08525                 INY                     ;
08526                 STY L.SECTORCNT         ;
08527
08528 LOOP064         LDA RANDOM              ; Load random sector 0..127 from GC memory map
08529                 AND #$7F                ;
08530                 TAY                     ;
08531                 LDA GCMEMMAP,Y          ;
08532                 BNE LOOP064             ; If sector already occupied, pick another
08533
08534                 LDA L.SECTORTYPE        ; Reload sector type
08535                 BPL SKIP196             ; Skip if sector not to be occupied by starbase
08536
08537                 CPY #$10                ; Place starbase...
08538                 BCC LOOP064             ; ...not in first sector row of Galactic Chart
08539                 CPY #$70                ;
08540                 BCS LOOP064             ; ...not in last sector row of Galactic Chart
08541                 TYA                     ;
08542                 AND #$0F                ;
08543                 BEQ LOOP064             ; ...not in first sector column of Galactic Chart
08544                 CMP #15                 ;
08545                 BEQ LOOP064             ; ...not in last sector column of Galactic Chart
08546                 LDA GCMEMMAP-1,Y        ; ...not east  of an occupied sector
08547                 ORA GCMEMMAP+1,Y        ; ...not west  of an occupied sector
08548                 ORA GCMEMMAP+16,Y       ; ...not south of an occupied sector
08549                 ORA GCMEMMAP-16,Y       ; ...not north of an occupied sector
08550                 BNE LOOP064             ;
08551
08552                 LDA L.SECTORTYPE        ; Reload sector type
08553
08554 SKIP196         STA GCMEMMAP,Y          ; Store sector type in Galactic Chart memory map
08555                 DEC L.SECTORCNT         ;
08556                 BPL LOOP064             ; Next sector
08557                 DEX                     ;
08558                 BPL LOOP063             ; Next sector type
08559
08560 ;*** Clear Galactic Chart and draw top border **********************************
08561                 LDX #180                ; Clear Galactic Chart PLAYFIELD
08562 LOOP065         LDA #CCS.SPC            ;
08563                 STA GCPFMEM-1,X         ;
08564                 DEX                     ;
08565                 BNE LOOP065             ;
08566
08567                 LDX #15                 ; Draw top border (15(+1) characters)
08568 LOOP066         LDA #CCS.BORDERS        ;
08569                 STA GCPFMEM+2,X         ;
08570                 DEX                     ;
08571                 BPL LOOP066             ;
08572
08573                 LDA #CCS.CORNERSW       ; Draw NORTHEAST corner (1 character)
08574                 STA GCPFMEM+18          ;
08575
08576                 LDA #0                  ; Release starship's position at center of Galactic
08577                 STA GCMEMMAP+4*16+8     ; ...Chart (sector row 4, sector column 8)
08578
08579 ;*** Initialize current sector and hyperwarp marker column and row numbers *****
08580                 LDA #$48                ; Place our starship's current sector at
08581                 STA CURRSECTOR          ; ...sector row 4, sector column 8
08582                 LDA #$43                ; Init departure & arrival hyperwarp marker column
08583                 STA WARPDEPRCOLUMN      ;
08584                 STA WARPARRVCOLUMN      ;
08585                 LDA #$47                ; Init departure & arrival hyperwarp marker row
08586                 STA WARPARRVROW         ;
08587                 STA WARPDEPRROW         ;
08588
08589 ;*** Tweak last entry of MAPTOBCD99 ********************************************
08590                 LDA #CCS.INF*16+CCS.SPC ; Last entry of MAPTOBCD99: 'INFINITY'+'SPACE' char
08591                 STA MAPTOBCD99+255      ;
08592
08593 ;*******************************************************************************
08594 ;*                                                                             *
08595 ;*                                   DRAWGC                                    *
08596 ;*                                                                             *
08597 ;*                             Draw Galactic Chart                             *
08598 ;*                                                                             *
08599 ;*******************************************************************************
08600
08601 ; DESCRIPTION
08602 ;
08603 ; Draws the content of the Galactic Chart memory map in GCMEMMAP ($08C9) to the
08604 ; Galactic Chart PLAYFIELD memory at GCPFMEM ($0D35). 
08605 ;
08606 ; NOTE: CPU register X indexes the Galactic Chart memory map GCMEMMAP ($08C9)
08607 ; (16 x 8 bytes). CPU register Y indexes the Galactic Chart PLAYFIELD memory
08608 ; GCPFMEM ($0D35) (20 x 9 bytes).
08609 ;
08610 ; NOTE: Sectors with 1 or 2 Zylon ships display the same symbol in the Galactic
08611 ; Chart.
08612
08613 L.GCMEMMAPIND   = $6A                   ; Saves Galactic Chart memory map index
08614
08615 DRAWGC          LDY #0                  ; Clear Galactic Chart PLAYFIELD memory index
08616                 STY L.GCMEMMAPIND       ; Clear Galactic Chart memory map index
08617
08618 LOOP067         LDX L.GCMEMMAPIND       ; Load sector of Galactic Chart memory map
08619                 LDA GCMEMMAP,X          ;
08620                 BPL SKIP197             ; Skip if not a starbase sector
08621                 LDA #5                  ; Prep sector character index for starbase
08622
08623 SKIP197         TAX                     ; Load sector character index
08624                 LDA SECTORCHARTAB,X     ; Load custom character set code from table...
08625                 STA GCPFMEM+22,Y        ; ...and store it in Galactic Chart PLAYFIELD memory
08626                 INY                     ; Increment Galactic Chart PLAYFIELD memory index
08627                 INC L.GCMEMMAPIND       ; Increment Galactic Chart memory map index
08628                 LDA L.GCMEMMAPIND       ;
08629                 AND #$0F                ;
08630                 BNE LOOP067             ; Next sector column until right border reached
08631
08632                 LDA #CCS.BORDERW        ; Draw right border
08633                 STA GCPFMEM+22,Y        ;
08634
08635                 INY                     ; Adjust Galactic Chart PLAYFIELD memory index
08636                 INY                     ;
08637                 INY                     ;
08638                 INY                     ;
08639                 CPY #$A0                ;
08640                 BCC LOOP067             ; Next sector until bottom-right sector reached
08641
08642                 RTS                     ; Return
08643
08644 ;*******************************************************************************
08645 ;*                                                                             *
08646 ;*                                FLUSHGAMELOOP                                *
08647 ;*                                                                             *
08648 ;*         Handle remaining tasks at the end of a game loop iteration          *
08649 ;*                                                                             *
08650 ;*******************************************************************************
08651
08652 ; DESCRIPTION
08653 ;
08654 ; This subroutine handles at the end of a game loop iteration the following
08655 ; tasks:
08656 ;
08657 ; (1)  Increment counters COUNT256 ($76) and COUNT8 ($72).
08658 ;
08659 ; (2)  If our starship's energy has dropped below 1000 units then flash a {PINK}
08660 ;      alert that changes to {DARK GREY BLUE} and back to {PINK} every 128 game
08661 ;      loop iterations.
08662 ;
08663 ; (3)  Set the Shields color and the Control Panel background color every 8 game
08664 ;      loop iterations:
08665 ;
08666 ;      o   If the Shields are up and OK then set the Shields color to {DARK
08667 ;          GREEN} and the Control Panel background color to {DARK BLUE}.
08668 ;
08669 ;      o   If the Shields are up and damaged there is a probability of 78%
08670 ;          (200:256) that the Shield color is not changed.
08671 ;
08672 ;      o   If the Shields are down, damaged, or destroyed then set the Shields
08673 ;          color to {BLACK}.
08674 ;
08675 ;      o   If the Shields are destroyed then set the Control Panel background
08676 ;          color to {ORANGE}.
08677 ;
08678 ; (4)  Decrement the lifetime of our starship's and Zylon photon torpedoes.
08679 ;
08680 ; (5)  Decrement the lifetime of an explosion. If the explosion lifetime is less
08681 ;      than 112 game loop iterations, clear HITBADNESS ($8A) (thus the explosion
08682 ;      cannot destroy our starship). If the explosion lifetime is less than 24
08683 ;      (?) game loops decrement the number of explosion fragments. This makes
08684 ;      explosion fragments disappear gradually toward the end of an explosion.
08685 ;
08686 ; (6)  Increment every 40 game loop iterations the stardate clock of the
08687 ;      Galactic Chart Panel Display.
08688 ;
08689 ; (7)  Move Zylon units in the Galactic Chart.
08690 ;
08691 ;      Every 50 game loop iterations (or 100 game loop iterations when a
08692 ;      starbase is surrounded by Zylon units) decrement the score.
08693 ;
08694 ; Code execution continues if the game is not in demo mode with the following
08695 ; steps:
08696 ;
08697 ; (1)  Search the Galactic Chart for starbases surrounded by Zylon units.
08698 ;      Destroy any such starbase: Replace it with a 2-Zylon sector and subtract
08699 ;      18 points from the score. If the Subspace Radio was not destroyed, then
08700 ;      flash the title phrase "STARBASE DESTROYED" and play the beeper sound
08701 ;      pattern MESSAGE FROM STARBASE in subroutine BEEP ($B3A6).
08702 ;
08703 ; (2)  Every 8 game loop iterations the Zylon units decide, which starbase to
08704 ;      hunt: First, 128 randomly picked sectors are searched for a starbase. If
08705 ;      no starbase was found in this way, the sectors of the Galactic Chart are
08706 ;      scanned systematically left-to-right, top-to-bottom. If a starbase was
08707 ;      found then its sector, sector column, and sector row are saved, otherwise
08708 ;      code execution returns.
08709 ;
08710 ; (3)  Now the Zylon units converge toward the sector of the hunted starbase:
08711 ;      All sectors of the Galactic Chart are scanned. For any sector with a
08712 ;      Zylon unit that was not moved yet (its sector does not have the temporary
08713 ;      "already-moved" bit B5 set) its movement probability value is picked from
08714 ;      table MOVEPROBTAB ($BFBB):
08715 ;
08716 ;      +---------------+-------------+----------------+
08717 ;      |  Sector Type  |  Movement   |   Movement     | 
08718 ;      |               | Probability |  Probability   |
08719 ;      |               |    Value    |                |
08720 ;      +---------------+-------------+----------------+
08721 ;      | Empty sector  |       0     |   0% (  0:256) | 
08722 ;      | 1 Zylon ship  |     255     | 100% (255:256) |
08723 ;      | 2 Zylon ships |     255     | 100% (255:256) | 
08724 ;      | 3 Zylon ships |     192     |  75% (192:256) | 
08725 ;      | 4 Zylon ships |      32     |  13% ( 32:256) |
08726 ;      +---------------+-------------+----------------+
08727 ;
08728 ;      If this value is less or equal than a random number in 0..255 then the
08729 ;      Zylon unit is moved to another sector. A Zylon unit that currently
08730 ;      occupies the sector of our starship is not moved.
08731 ;
08732 ;      BUG (at $B620): The instruction to check the marker bit B5 of the sector
08733 ;      is CPY #$0A. This works, as sectors containing Zylon units that need to
08734 ;      be moved have values of 2..4, see table SECTORTYPETAB ($BBA6). Suggested
08735 ;      fix: Replace CPY #$0A with CPY #$20, which may make the code clearer.
08736 ;
08737 ; (4)  For every Zylon unit that is about to be moved, 9 distances ("block
08738 ;      distances") between the Zylon unit and the starbase are calculated by
08739 ;      tentatively moving the Zylon unit into each of its 8 adjacent sectors -
08740 ;      and by moving it not at all. The sector offsets are taken from table
08741 ;      COMPASSOFFTAB ($BFC0) which stores direction offsets in the following
08742 ;      order: NORTH, NORTHWEST, WEST, SOUTHWEST, SOUTH, SOUTHEAST, EAST,
08743 ;      NORTHEAST, CENTER. All 9 distances are stored in 9 consecutive bytes at
08744 ;      NEWZYLONDIST ($96).
08745 ;
08746 ;      NOTE: The last calculated distance is the current distance between Zylon
08747 ;      unit and starbase.
08748 ;
08749 ;      The Zylon unit moves to the first of the 8 adjacent sectors that matches
08750 ;      the following conditions: 
08751 ;
08752 ;      (1)  It is closer to the starbase than the Zylon unit's current sector.
08753 ;
08754 ;      (2)  It is located inside the Galactic Chart.
08755 ;
08756 ;      (3)  It is empty.
08757 ;
08758 ;      (4)  It is not the sector containing our starship.
08759 ;
08760 ;      If a suitable new sector was found then the Zylon unit is moved to this
08761 ;      sector, which is marked with the "already-moved" marker bit B5 in the
08762 ;      Galactic Chart memory map. This marker bit prevents a Zylon unit that has
08763 ;      been already moved from being moved again. The old Zylon unit sector is
08764 ;      cleared. 
08765 ;
08766 ;      If no suitable new sector was found then the above distance calculations
08767 ;      are repeated once again by adding 1 to the current distance between the
08768 ;      Zylon unit and the starbase. This may provoke a Zylon unit to move that
08769 ;      would not have moved in the previous set of distance calculations.
08770 ;
08771 ;      After having moved all Zylon units the sectors are stripped of the
08772 ;      "already-moved" marker bit B5.
08773 ;
08774 ; (5)  If a starbase has been surrounded then the Zylon unit movement timer is
08775 ;      reset to 99, buying our starship some time to destroy one of the
08776 ;      surrounding Zylon units. If the Subspace Radio is not destroyed, then the
08777 ;      message "STARBASE SURROUNDED" is flashed in the title line and the beeper
08778 ;      sound pattern MESSAGE FROM STARBASE is played in subroutine BEEP ($B3A6).
08779
08780 L.ISDESTROYED   = $6A                   ; Flags the destruction of a starbase.
08781                                         ; Used values are:
08782                                         ;   $00 -> Starbase not destroyed
08783                                         ;   $02 -> Starbase has been destroyed
08784 L.NEWSECTOR     = $6A                   ; Sector to which the Zylon unit is tentatively moved
08785 L.ABSDIFFCOLUMN = $6B                   ; Absolute difference between new Zylon and starbase
08786                                         ;   column on Galactic Chart in PM pixels
08787 L.LOOPCNT2      = $6B                   ; Loop counter. Used values are: 0..1.
08788 L.DIRECTIONIND  = $6A                   ; Compass rose direction index.
08789                                         ; Used values are: 0..7.
08790
08791 ;*** Increment counters and flash low-energy alert *****************************
08792 FLUSHGAMELOOP   INC COUNT256            ; Increment COUNT256 counter
08793
08794                 LDX #$90                ; Prep DLI background color {DARK GREY BLUE}
08795                 LDA COUNT256            ;
08796                 BPL SKIP198             ; Skip if counter < 128.
08797
08798                 LDY ENERGYD1            ; When energy drops below 1000 units...
08799                 CPY #CCS.COL2!CCS.0     ;
08800                 BNE SKIP198             ;
08801                 LDX #$44                ; ...prep new DLI background color {PINK}
08802
08803 SKIP198         AND #$03                ; Increment COUNT8
08804                 STA COUNT8              ;
08805                 BNE SKIP202             ; Skip setting colors but every 8 game loops
08806
08807 ;*** Set Shields and Control Panel background color ****************************
08808                 LDY DRAINSHIELDS        ; Skip if Shields are off
08809                 BEQ SKIP201             ;
08810
08811                 LDY #$A0                ; Prep Shields color {DARK GREEN}
08812                 BIT GCSTATSHL           ; Skip if Shields are OK
08813                 BPL SKIP200             ;
08814                 BVS SKIP199             ; Skip if Shields are destroyed
08815                 LDA RANDOM              ; If Shields are damaged, Shields colors are...
08816                 CMP #200                ; ...unchanged with probability of 78% (200:256)
08817                 BCC SKIP201             ;
08818
08819 SKIP199         LDY #$00                ; Prep Shields color {BLACK}
08820 SKIP200         TYA                     ;
08821                 BNE SKIP201             ;
08822
08823                 LDX #$26                ; Prep Control Panel background color {ORANGE}
08824
08825 SKIP201         STY SHIELDSCOLOR        ; Store Shields color
08826                 STX BGRCOLORDLI         ; Store Control Panel background color
08827
08828 ;*** Decrement lifetime of our starship's and Zylon photon torpedoes ***********
08829 SKIP202         LDX #2                  ; Loop over PLAYER2..4
08830
08831 LOOP068         LDA PL2SHAPTYPE,X       ; Next PLAYER if not PHOTON TORPEDO (shape type 0)
08832                 BNE SKIP203             ;
08833
08834                 LDA PL2LIFE,X           ; Next PLAYER if this PLAYER not alive
08835                 BEQ SKIP203             ;
08836
08837                 DEC PL2LIFE,X           ; Decrement photon torpedo PLAYER lifetime
08838
08839 SKIP203         DEX                     ;
08840                 BPL LOOP068             ; Next PLAYER
08841
08842 ;*** Decrement lifetime of explosion *******************************************
08843                 LDA EXPLLIFE            ; Skip if explosion lifetime expired
08844                 BEQ SKIP206             ;
08845
08846                 DEC EXPLLIFE            ; Decrement explosion lifetime
08847                 BNE SKIP204             ; Skip if explosion lifetime still counting
08848
08849                 LDX #NUMSPCOBJ.NORM     ; Explosion finished,...
08850                 STX MAXSPCOBJIND        ; ...restore normal number of space objects
08851
08852 SKIP204         CMP #112                ; Skip if explosion lifetime >= 112 game loops
08853                 BCS SKIP205             ;
08854
08855                 LDX #0                  ; HITBADNESS := NO HIT
08856                 STX HITBADNESS          ;
08857
08858 SKIP205         CMP #24                 ; Skip if explosion lifetime >= 24 game loops (?)
08859                 BCS SKIP206             ;
08860
08861                 DEC MAXSPCOBJIND        ; Decrement number of explosion fragment space objs
08862
08863 ;*** Increment stardate clock **************************************************
08864 SKIP206         DEC CLOCKTIM            ; Decrement stardate clock timer
08865                 BPL SKIP209             ; Return if timer is still counting
08866
08867                 LDA #40                 ; Reset stardate clock timer to 40 game loops
08868                 STA CLOCKTIM            ;
08869
08870                 LDX #4                  ; Increment stardate clock of Galactic Chart Panel
08871 LOOP069         INC GCSTARDAT,X         ;
08872                 LDA GCSTARDAT,X         ;
08873                 CMP #[CCS.COL3!ROM.9]+1 ;
08874                 BCC SKIP208             ;
08875                 LDA #[CCS.COL3!ROM.0]   ;
08876                 STA GCSTARDAT,X         ;
08877                 CPX #3                  ;
08878                 BNE SKIP207             ;
08879                 DEX                     ;
08880 SKIP207         DEX                     ;
08881                 BPL LOOP069             ;
08882
08883 ;*** Decrement Zylon unit movement timer ***************************************
08884 SKIP208         DEC ZYLONUNITTIM        ; Decrement Zylon unit movement timer
08885                 BMI SKIP210             ; If timer < 0 move Zylon units
08886
08887 SKIP209         RTS                     ; Return
08888
08889 ;*** Restore Zylon unit movement timer and decrement score *********************
08890 SKIP210         LDA #49                 ; Reset Zylon unit movement timer to 49
08891                 STA ZYLONUNITTIM        ;
08892
08893                 LDA SCORE               ; SCORE := SCORE - 1
08894                 BNE SKIP211             ;
08895                 DEC SCORE+1             ;
08896 SKIP211         DEC SCORE               ;
08897
08898                 LDX ISDEMOMODE          ; Return if in demo mode
08899                 BNE SKIP209             ;
08900
08901 ;*** Is starbase surrounded? ***************************************************
08902                 STX L.ISDESTROYED       ; Init L.ISDESTROYED with 0 (starbase not destroyed)
08903 LOOP070         LDA GCMEMMAP,X          ; Loop over all sectors, load sector type
08904                 BPL SKIP212             ; Skip if not a starbase sector
08905
08906                 JSR ISSURROUNDED        ; Skip if starbase sector not completely surrounded
08907                 BEQ SKIP212             ;
08908
08909 ;*** Starbase is surrounded, destroy starbase **********************************
08910                 LDA #2                  ; Replace starbase sector with 2-Zylon sector
08911                 STA GCMEMMAP,X          ;
08912                 STA L.ISDESTROYED       ; Flag destruction of starbase
08913
08914                 SEC                     ; SCORE := SCORE - 18
08915                 LDA SCORE               ;
08916                 SBC #18                 ;
08917                 STA SCORE               ;
08918                 LDA SCORE+1             ;
08919                 SBC #0                  ;
08920                 STA SCORE+1             ;
08921
08922 SKIP212         INX                     ;
08923                 BPL LOOP070             ; Next sector
08924
08925 ;*** Report starbase destruction ***********************************************
08926                 LDA L.ISDESTROYED       ; Skip if no starbase has been destroyed
08927                 BEQ SKIP213             ;
08928
08929                 BIT GCSTATRAD           ; Skip notification if Subspace Radio destroyed
08930                 BVS SKIP213             ;
08931
08932                 LDY #$15                ; Set title phrase "STARBASE DESTROYED"
08933                 JSR SETTITLE            ;
08934
08935                 LDX #$18                ; Play beeper sound pattern MESSAGE FROM STARBASE
08936                 JSR BEEP                ;
08937
08938 ;*** Pick new starbase to be hunted by Zylon units *****************************
08939 SKIP213         DEC HUNTTIM             ; Decrement hunting timer
08940                 BMI SKIP214             ; If timer < 0 decide which starbase to hunt
08941
08942                 LDX HUNTSECTOR          ; Skip if Zylon units already picked starbase to hunt
08943                 LDA GCMEMMAP,X          ;
08944                 BMI SKIP215             ;
08945
08946 SKIP214         LDA #7                  ; Reset hunting timer
08947                 STA HUNTTIM             ;
08948
08949                 LDY #127                ; Loop over 127(+1) randomly picked sectors
08950 LOOP071         LDA RANDOM              ;
08951                 AND #$7F                ;
08952                 TAX                     ;
08953                 LDA GCMEMMAP,X          ; Skip if starbase sector found
08954                 BMI SKIP215             ;
08955                 DEY                     ;
08956                 BPL LOOP071             ; Next sector
08957
08958                 LDX #127                ; Loop over all sectors of the Galactic Chart
08959 LOOP072         LDA GCMEMMAP,X          ;
08960                 BMI SKIP215             ; Skip if starbase sector found
08961                 DEX                     ;
08962                 BPL LOOP072             ; Next sector
08963
08964                 RTS                     ; Return (no starbase sector found)
08965
08966 ;*** Store coordinates of starbase to be hunted ********************************
08967 SKIP215         STX HUNTSECTOR          ; Store hunted starbase sector column and row
08968                 TXA                     ;
08969                 AND #$0F                ;
08970                 STA HUNTSECTCOLUMN      ;
08971                 TXA                     ;
08972                 LSR A                   ;
08973                 LSR A                   ;
08974                 LSR A                   ;
08975                 LSR A                   ;
08976                 STA HUNTSECTROW         ;
08977
08978 ;*** Move all Zylon units toward hunted starbase *******************************
08979                 LDX #$FF                ;
08980 LOOP073         INX                     ; Loop over all sectors to move Zylon units
08981                 BPL SKIP218             ; Jump into loop body below
08982
08983 ;*** Strip marker bits from moved Zylon units **********************************
08984                 LDX #0                  ;
08985 LOOP074         LDA GCMEMMAP,X          ; Loop over all sectors
08986                 AND #$DF                ;
08987                 STA GCMEMMAP,X          ; Strip marker bit B5 from moved Zylon units
08988                 INX                     ;
08989                 BPL LOOP074             ; Next sector
08990
08991 ;*** Handle surrounded starbase ************************************************
08992                 BIT GCSTATRAD           ; Return if Subspace Radio is destroyed
08993                 BVS SKIP217             ;
08994
08995                 LDX #0                  ; Loop over all sectors
08996 LOOP075         LDA GCMEMMAP,X          ;
08997                 BPL SKIP216             ; Skip if not a starbase sector
08998                 JSR ISSURROUNDED        ; Skip if starbase not surrounded
08999                 BEQ SKIP216             ;
09000
09001                 LDA #99                 ; Yes, starbase surrounded...
09002                 STA ZYLONUNITTIM        ; ...set Zylon unit movement timer to 99
09003
09004                 LDY #$13                ; Set title phrase "STARBASE SURROUNDED"
09005                 JSR SETTITLE            ;
09006
09007                 LDX #$18                ; Play beeper sound pattern MESSAGE FROM STARBASE...
09008                 JMP BEEP                ; ...and return
09009
09010 SKIP216         INX                     ;
09011                 BPL LOOP075             ; Next sector
09012
09013 SKIP217         RTS                     ; Return
09014
09015 ;*** Move single Zylon unit ****************************************************
09016 SKIP218         LDY GCMEMMAP,X          ; X contains current sector
09017                 CPY #$0A                ; Next sector if it has marker bit B5 set (!)
09018                 BCS LOOP073             ;
09019
09020                 LDA RANDOM              ; Get random number
09021                 CMP MOVEPROBTAB,Y       ; Get movement probability
09022                 BCS LOOP073             ; Next sector if movement probability < random number
09023
09024                 CPX CURRSECTOR          ; Next sector if this is our starship's sector
09025                 BEQ LOOP073             ;
09026
09027 ;*** Compute distance to starbase by moving Zylon unit into 9 directions *******
09028                 LDY #8                  ; Loop over 8(+1) possible directions
09029 LOOP076         CLC                     ;
09030                 TXA                     ;
09031                 ADC COMPASSOFFTAB,Y     ; Add direction offset to current sector
09032                 STA L.NEWSECTOR         ; Store new sector
09033
09034                 AND #$0F                ; Calc distance ("block distance") between...
09035                 SEC                     ; ...starbase sector and tentative new Zylon sector
09036                 SBC HUNTSECTCOLUMN      ;
09037                 BCS SKIP219             ;
09038                 EOR #$FF                ;
09039                 ADC #1                  ;
09040 SKIP219         STA L.ABSDIFFCOLUMN     ;
09041                 LDA L.NEWSECTOR         ;
09042                 LSR A                   ;
09043                 LSR A                   ;
09044                 LSR A                   ;
09045                 LSR A                   ;
09046                 SEC                     ;
09047                 SBC HUNTSECTROW         ;
09048                 BCS SKIP220             ;
09049                 EOR #$FF                ;
09050                 ADC #1                  ;
09051 SKIP220         CLC                     ;
09052                 ADC L.ABSDIFFCOLUMN     ;
09053
09054                 STA NEWZYLONDIST,Y      ; Store distance in distance array
09055                 DEY                     ;
09056                 BPL LOOP076             ; Next direction
09057
09058 ;*** Pick the shortest distance to starbase ************************************
09059                 LDA #1                  ; Loop over compass rose directions twice to...
09060                 STA L.LOOPCNT2          ; ...provoke movement regardless of truncation errors
09061
09062 LOOP077         LDY #7                  ;
09063 LOOP078         LDA NEWZYLONDIST,Y      ; Loop over all 7(+1) compass rose directions
09064                 CMP OLDZYLONDIST        ;
09065                 BCS SKIP222             ; Next direction if new distance > current distance
09066
09067                 CLC                     ; Calc new Galactic Chart sector for Zylon unit
09068                 TXA                     ;
09069                 ADC COMPASSOFFTAB,Y     ;
09070                 BMI SKIP222             ; Next direction if new sector outside Galactic Chart
09071
09072                 STY L.DIRECTIONIND      ; Save compass rose direction index
09073                 TAY                     ;
09074                 LDA GCMEMMAP,Y          ;
09075                 BNE SKIP221             ; Next direction if new sector not empty
09076
09077                 LDA GCMEMMAP,X          ; Preload Zylon sector type to be moved
09078                 CPY CURRSECTOR          ;
09079                 BEQ SKIP221             ; Next direction if sector is our starship's sector
09080
09081                 ORA #$20                ; New sector for Zylon unit found!
09082                 STA GCMEMMAP,Y          ; Temporarily mark that sector with marker bit B5
09083                 LDA #0                  ;
09084                 STA GCMEMMAP,X          ; Clear old Zylon unit sector
09085                 BEQ SKIP223             ; Next sector (unconditional branch)
09086
09087 SKIP221         LDY L.DIRECTIONIND      ; Restore compass rose direction index
09088 SKIP222         DEY                     ; Next compass rose direction
09089                 BPL LOOP078             ;
09090
09091                 INC OLDZYLONDIST        ; Increment center distance
09092                 DEC L.LOOPCNT2          ;
09093                 BPL LOOP077             ; Loop over all compass rose directions one more time
09094
09095 SKIP223         JMP LOOP073             ; Next sector
09096
09097 ; *******************************************************************************
09098 ; *                                                                             *
09099 ; *                                   ROTATE                                    *
09100 ; *                                                                             *
09101 ; *        Rotate position vector component (coordinate) by fixed angle         *
09102 ; *                                                                             *
09103 ; *******************************************************************************
09104
09105 ; DESCRIPTION
09106 ;
09107 ; This subroutine rotates a position vector component (coordinate) of a space
09108 ; object by a fixed angle around the center of the 3D coordinate system, the
09109 ; location of our starship. This is used in the Front, Aft, and Long-Range Scan
09110 ; views to rotate space objects in and out of the view. Although the code is
09111 ; deceptively short, there is some interesting math involved, so a more detailed
09112 ; discussion is in order.
09113 ;
09114 ; ROTATION MATHEMATICS
09115 ;
09116 ; The game uses a left-handed 3D coordinate system with the positive x-axis
09117 ; pointing to the right, the positive y-axis pointing up, and the positive
09118 ; z-axis pointing into flight direction.
09119 ;
09120 ; A rotation in this coordinate system around the y-axis (horizontal rotation)
09121 ; can be expressed as 
09122 ;
09123 ;     x' :=   cos(ry) * x + sin(ry) * z    (1a)
09124 ;     z' := - sin(ry) * x + cos(ry) * z    (1b)
09125 ;
09126 ; where ry is the clockwise rotation angle around the y-axis, x and z are the
09127 ; coordinates before this rotation, and the primed coordinates x' and z' the
09128 ; coordinates after this rotation. The y-coordinate is not changed by this
09129 ; rotation.
09130 ;
09131 ; A rotation in this coordinate system around the x-axis (vertical rotation) can
09132 ; be expressed as 
09133 ;
09134 ;     z' :=   cos(rx) * z + sin(rx) * y    (2a)
09135 ;     y' := - sin(rx) * z + cos(rx) * y    (2b)
09136 ;
09137 ; where rx is the clockwise rotation angle around the x-axis, z and y are the
09138 ; coordinates before this rotation, and the primed coordinates z' and y' the
09139 ; coordinates after this rotation. The x-coordinate is not changed by this
09140 ; rotation.
09141 ;
09142 ; SUBROUTINE IMPLEMENTATION OVERVIEW
09143 ;
09144 ; A single call of this subroutine is able to compute one of the four
09145 ; expressions (1a)-(2b). To compute all four expressions to get the new set of
09146 ; coordinates, this subroutine has to be called four times. This is done twice
09147 ; in pairs in GAMELOOP ($A1F3) at $A391 and $A398, and at $A3AE and $A3B5,
09148 ; respectively.
09149 ;
09150 ; The first pair of calls calculates the new x and z coordinates of a space
09151 ; object due to a horizontal (left/right) rotation of our starship around the
09152 ; y-axis following expressions (1a) and (1b).
09153 ;
09154 ; The second pair of calls calculates the new y and z coordinates of the same
09155 ; space object due to a vertical (up/down) rotation of our starship around the
09156 ; x-axis following expressions (2a) and (2b).
09157 ;
09158 ; If you look at the code, you may be wondering how this calculation is actually
09159 ; executed, as there is neither a sin() nor a cos() function call. What you'll
09160 ; actually find implemented, however, are the following calculations:
09161 ;
09162 ;     Joystick left                        Joystick right
09163 ;     ---------------------                ---------------------
09164 ;     x :=  x      + z / 64    (3a)        x :=  x      - z / 64    (4a)
09165 ;     z := -x / 64 + z         (3b)        z :=  x / 64 + z         (4b)
09166 ;
09167 ;     Joystick down                        Joystick up
09168 ;     ---------------------                ---------------------
09169 ;     y :=  y      + z / 64    (5a)        y :=  y      - z / 64    (6a)
09170 ;     z := -y / 64 + z         (5b)        z :=  y / 64 + z         (6b)
09171 ;
09172 ; CORDIC ALGORITHM
09173 ;
09174 ; When you compare expressions (1a)-(2b) with (3a)-(6b), notice the similarity
09175 ; between the expressions if you substitute
09176 ;
09177 ;     sin(ry) -> 1 / 64, 
09178 ;     cos(ry) -> 1,
09179 ;     sin(rx) -> 1 / 64, and
09180 ;     cos(rx) -> 1.
09181 ;
09182 ; From sin(ry) = 1 / 64 and sin(rx) = 1 / 64 you can derive that the rotation
09183 ; angles ry and rx by which the space object is rotated per game loop iteration
09184 ; have a constant value of 0.89 degrees, as arcsine(1 / 64) = 0.89 degrees.
09185 ;
09186 ; What about cos(ry) and cos(rx)? The substitution does not match our derived
09187 ; angle exactly, because cos(0.89 degrees) = 0.99988 and is not exactly 1.
09188 ; However, this value is so close to 1 that substituting cos(0.89 degrees) with
09189 ; 1 is a very good approximation, simplifying calculations significantly.
09190 ;
09191 ; Another significant simplification results from the division by 64, because
09192 ; the actual division operation can be replaced with a much faster bit shift
09193 ; operation.
09194 ;
09195 ; This calculation-friendly way of computing rotations is known as the "CORDIC
09196 ; (COordinate Rotation DIgital Computer)" algorithm.
09197 ;
09198 ; MINSKY ROTATION
09199 ;
09200 ; There is one more interesting mathematical subtlety: Did you notice that
09201 ; expressions (1a)-(2b) use a new (primed) pair of variables to store the
09202 ; resulting coordinates, whereas in the implemented expressions (3a)-(6b) the
09203 ; value of the first coordinate of a coordinate pair is overwritten with its new
09204 ; value and this value is used in the subsequent calculation of the second
09205 ; coordinate? For example, when the joystick is pushed left, the first call of
09206 ; this subroutine calculates the new value of x according to expression (3a),
09207 ; overwriting the old value of x. During the second call to calculate z
09208 ; according to expression (3b), the new value of x is used instead of the old
09209 ; one. Is this to save the memory needed to temporarily store the old value of
09210 ; x? Is this a bug? If so, why does the rotation calculation actually work?
09211 ;
09212 ; Have a look at the expression pair (3a) and (3b) (the other expression pairs
09213 ; (4a)-(6b) work in a similar fashion):
09214 ;
09215 ;     x :=  x      + z / 64
09216 ;     z := -x / 64 + z
09217 ;
09218 ; With the substitution 1 / 64 -> e, we get
09219 ;
09220 ;     x :=  x     + e * z
09221 ;     z := -e * x + z
09222 ;
09223 ; Note that x is calculated first and then used in the second expression. When
09224 ; using primed coordinates for the resulting coordinates after calculating the
09225 ; two expressions we get
09226 ;
09227 ;     x' := x + e * z
09228 ;     z' := -e * x' + z = -e * (x + e * z) + z = -e * x + (1 - e^2) * z
09229 ;
09230 ; or in matrix form
09231 ;
09232 ;     |x'| := | 1       e   | * |x|
09233 ;     |z'|    |-e  (1 - e^2)|   |z|
09234 ;
09235 ; Surprisingly, this turns out to be a rotation matrix, because its determinant
09236 ; is (1 * (1 - e^2) - (e * -e)) = 1.
09237 ;
09238 ; (Incidentally, the column vectors of this matrix do not form an orthogonal
09239 ; basis, as their scalar product is 1 * e + (-e * (1 - e^2)) = -e^2.
09240 ; Orthogonality holds for e = 0 only.)
09241 ;
09242 ; This kind of rotation calculation is described by Marvin Minsky in ["AIM 239
09243 ; HAKMEM", Item 149, p. 73, MIT AI Lab, February 1972] and is called "Minsky
09244 ; Rotation".
09245 ;
09246 ; SUBROUTINE IMPLEMENTATION DETAILS
09247 ;
09248 ; To better understand how the implementation of this subroutine works, have
09249 ; again a look at expressions (3a)-(6b). If you rearrange the expressions a
09250 ; little their structure is always of the form
09251 ;
09252 ;     TERM1 := TERM1 SIGN TERM2 / 64
09253 ;
09254 ;     or shorter
09255 ;
09256 ;     TERM1 := TERM1 SIGN TERM3
09257 ;
09258 ;     where
09259 ;
09260 ;     TERM3 := TERM2 / 64
09261 ;     SIGN := + or -
09262 ;
09263 ; and where TERM1 and TERM2 are position vector components (coordinates). In
09264 ; fact, this is all this subroutine actually does: It simply adds TERM2 divided
09265 ; by 64 to TERM1 or subtracts TERM2 divided by 64 from TERM1. 
09266 ;
09267 ; When calling this subroutine the correct indices for the appropriate position
09268 ; vector components (coordinates) TERM1 and TERM2 are passed in the Y and X
09269 ; registers, respectively.
09270 ;
09271 ; What about SIGN between TERM1 and TERM3? Have again a look at expressions
09272 ; (3a)-(6b). To compute the two new coordinates after a rotation, the SIGN
09273 ; toggles from plus to minus and vice versa. The SIGN is initialized with
09274 ; JOYSTICKDELTA ($6D) before calling subroutine ROTATE ($B69B) and is toggled
09275 ; inside every call of this subroutine before the addition or subtraction of the
09276 ; terms takes place there. The initial value of SIGN should be positive (+) if
09277 ; the rotation is clockwise (the joystick is pushed right or up) and negative
09278 ; (-) if the rotation is counter-clockwise (the joystick is pushed left or
09279 ; down), respectively. Because SIGN is always toggled inside the subroutine
09280 ; before the addition or subtraction of the terms actually happens there, you
09281 ; have to pass the already toggled value with the first call.
09282 ;
09283 ; NOTE: Unclear still are three instructions starting at address $B6AD. They
09284 ; seem to set the two least significant bits of TERM3 in a random fashion. Could
09285 ; this be some quick hack to avoid messing with exact but potentially lengthy
09286 ; two-complement's arithmetic here?
09287 ;
09288 ; INPUT
09289 ;
09290 ;   X = Position vector component index of TERM2. Used values are:
09291 ;     $00..$30 -> z-component (z-coordinate) of position vector 0..48
09292 ;     $31..$61 -> x-component (x-coordinate) of position vector 0..48
09293 ;     $62..$92 -> y-component (y-coordinate) of position vector 0..48
09294 ;
09295 ;   Y = Position vector component index of TERM1. Used values are: 
09296 ;     $00..$30 -> z-component (z-coordinate) of position vector 0..48
09297 ;     $31..$61 -> x-component (x-coordinate) of position vector 0..48
09298 ;     $62..$92 -> y-component (y-coordinate) of position vector 0..48
09299 ;
09300 ;   JOYSTICKDELTA ($6D) = Initial value of SIGN. Used values are:
09301 ;     $01 -> (= Positive) Rotate right or up
09302 ;     $FF -> (= Negative) Rotate left or down
09303
09304                                         ; TERM3 is a 24-bit value, represented by 3 bytes as
09305                                         ; $(sign)(high byte)(low byte)
09306 L.TERM3LO       = $6A                   ; TERM3 (high byte), where TERM3 := TERM2 / 64
09307 L.TERM3HI       = $6B                   ; TERM3 (low byte),  where TERM3 := TERM2 / 64
09308 L.TERM3SIGN     = $6C                   ; TERM3 (sign),      where TERM3 := TERM2 / 64
09309
09310 ROTATE          LDA ZPOSSIGN,X          ;
09311                 EOR #$01                ;
09312                 BEQ SKIP224             ; Skip if sign of TERM2 is positive
09313                 LDA #$FF                ;
09314
09315 SKIP224         STA L.TERM3HI           ; If TERM2 pos. -> TERM3 := $0000xx (= TERM2 / 256)
09316                 STA L.TERM3SIGN         ; If TERM2 neg. -> TERM3 := $FFFFxx (= TERM2 / 256)
09317                 LDA ZPOSHI,X            ; where xx := TERM2 (high byte)
09318                 STA L.TERM3LO           ;
09319
09320                 LDA RANDOM              ; (?) Hack to avoid messing with two-complement's
09321                 ORA #$BF                ; (?) arithmetic? Provides two least significant
09322                 EOR ZPOSLO,X            ; (?) bits B1..0 in TERM3.
09323
09324                 ASL A                   ; TERM3 := TERM3 * 4 (= TERM2 / 256 * 4 = TERM2 / 64)
09325                 ROL L.TERM3LO           ;
09326                 ROL L.TERM3HI           ;
09327                 ASL A                   ;
09328                 ROL L.TERM3LO           ;
09329                 ROL L.TERM3HI           ;
09330
09331                 LDA JOYSTICKDELTA       ; Toggle SIGN for next call of ROTATE
09332                 EOR #$FF                ;
09333                 STA JOYSTICKDELTA       ;
09334                 BMI SKIP225             ; If SIGN negative then subtract, else add TERM3
09335
09336 ;*** Addition ******************************************************************
09337                 CLC                     ; TERM1 := TERM1 + TERM3
09338                 LDA ZPOSLO,Y            ; (24-bit addition)
09339                 ADC L.TERM3LO           ;
09340                 STA ZPOSLO,Y            ;
09341
09342                 LDA ZPOSHI,Y            ;
09343                 ADC L.TERM3HI           ;
09344                 STA ZPOSHI,Y            ;
09345
09346                 LDA ZPOSSIGN,Y          ;
09347                 ADC L.TERM3SIGN         ;
09348                 STA ZPOSSIGN,Y          ;
09349                 RTS                     ;
09350
09351 ;*** Subtraction ***************************************************************
09352 SKIP225         SEC                     ; TERM1 := TERM1 - TERM3
09353                 LDA ZPOSLO,Y            ; (24-bit subtraction)
09354                 SBC L.TERM3LO           ;
09355                 STA ZPOSLO,Y            ;
09356
09357                 LDA ZPOSHI,Y            ;
09358                 SBC L.TERM3HI           ;
09359                 STA ZPOSHI,Y            ;
09360
09361                 LDA ZPOSSIGN,Y          ;
09362                 SBC L.TERM3SIGN         ;
09363                 STA ZPOSSIGN,Y          ;
09364                 RTS                     ;
09365
09366 ;*******************************************************************************
09367 ;*                                                                             *
09368 ;*                                SCREENCOLUMN                                 *
09369 ;*                                                                             *
09370 ;*       Calculate pixel column number from centered pixel column number       *
09371 ;*                                                                             *
09372 ;*******************************************************************************
09373
09374 ; DESCRIPTION
09375 ;
09376 ; Converts a pixel column number relative to the horizontal screen center to a
09377 ; pixel column number relative to the top-left corner of the screen and stores
09378 ; the result in table PIXELCOLUMN ($0C2A). The passed relative pixel column
09379 ; number is always positive. The sign is picked from the corresponding
09380 ; x-component of the position vector (x-coordinate).
09381 ;
09382 ; If the passed relative pixel column number is offscreen horizontally the
09383 ; calculation is skipped and code execution returns. If the position vector
09384 ; corresponding to this pixel represents a PLAYFIELD space object (star,
09385 ; explosion fragments) a new position vector is initialized before code
09386 ; execution returns. If it represents a PLAYER space object the PLAYER is pushed
09387 ; offscreen before code execution returns.
09388 ;
09389 ; NOTE: The horizontal screen center's pixel column number for PLAYFIELD space
09390 ; objects has a value of 80 = 160 PLAYFIELD pixels / 2. For PLAYER space objects
09391 ; it has a value of 125 Player/Missile (PM) pixels (from left to right: 128 PM
09392 ; pixels to the horizontal screen center - 3 PM pixels relative offset of the
09393 ; PLAYER shape's horizontal center to its left edge = 125 PM pixels).
09394 ;
09395 ; INPUT
09396 ;
09397 ;   A = Pixel column number relative to the horizontal screen center, always
09398 ;       positive. Used values are:
09399 ;     0..80 -> Regular values, pixel is onscreen
09400 ;     $FF   -> Pixel is offscreen
09401 ;
09402 ;   X = Position vector index. Used values are:
09403 ;     0..4  -> Position vector of a PLAYER space object
09404 ;     5..48 -> Position vector of a PLAYFIELD space object
09405
09406 L.PIXELCOLUMN   = $6D                   ; Saves relative pixel column number
09407
09408 SCREENCOLUMN    CMP #80                 ; If pixel is offscreen (A > 79)...
09409                 BCS SKIP233             ; ...return via initializing a new position vector
09410
09411                 STA L.PIXELCOLUMN       ; Save relative pixel column number
09412                 LDA #80                 ; If PLAYFIELD space object -> A := CENTERCOL = 80
09413                 CPX #NUMSPCOBJ.PL       ; If PLAYER space object    -> A := CENTERCOL = 125
09414                 BCS SKIP226             ;
09415                 LDA #125                ;
09416
09417 SKIP226         LDY XPOSSIGN,X          ; Skip if x-coordinate positive
09418                 BNE SKIP227             ;
09419
09420                 SEC                     ; Pixel in left screen half (x-coordinate negative)
09421                 INC L.PIXELCOLUMN       ;
09422                 SBC L.PIXELCOLUMN       ;
09423                 STA PIXELCOLUMN,X       ; Pixel column := CENTERCOL - (rel. pixel column + 1)
09424                 RTS                     ; Return
09425
09426 SKIP227         CLC                     ; Pixel in right screen half (x-coordinate positive)
09427                 ADC L.PIXELCOLUMN       ;
09428                 STA PIXELCOLUMN,X       ; Pixel column := CENTERCOL + relative pixel column
09429                 RTS                     ; Return
09430
09431 ;*******************************************************************************
09432 ;*                                                                             *
09433 ;*                                  SCREENROW                                  *
09434 ;*                                                                             *
09435 ;*          Calculate pixel row number from centered pixel row number          *
09436 ;*                                                                             *
09437 ;*******************************************************************************
09438
09439 ; Converts a pixel row number relative to the vertical screen center to a pixel
09440 ; row number relative to the top-left corner of the screen and stores the result
09441 ; in table PIXELROWNEW ($0BF9). The passed relative pixel row number is always
09442 ; positive. The sign is picked from the corresponding y-component of the
09443 ; position vector (y-coordinate).
09444 ;
09445 ; If the passed relative pixel row number is offscreen vertically the
09446 ; calculation is skipped and code execution returns. If the position vector
09447 ; corresponding to this pixel represents a PLAYFIELD space object (star,
09448 ; explosion fragments) a new position vector is initialized in subroutine
09449 ; INITPOSVEC ($B764) before code execution returns. If it represents a PLAYER
09450 ; space object the PLAYER is pushed offscreen before code execution returns.
09451 ;
09452 ; NOTE: The vertical screen center's pixel row number for PLAYFIELD space
09453 ; objects has a value of 50 = 100 PLAYFIELD pixels / 2. For PLAYER space objects
09454 ; it has a value of 122 Player/Missile (PM) pixels (from top to bottom: 8 PM
09455 ; pixels to start of Display List + 16 PM pixels to begin of PLAYFIELD + 100 PM
09456 ; pixels to vertical screen center - 2 PM pixels (?) = 122 PM pixels).
09457 ;
09458 ; NOTE: If the position vector corresponding to the pixel represents a PLAYER
09459 ; space object the passed pixel row number is doubled because 1 PLAYFIELD pixel
09460 ; has the same height as 2 PM pixels at single-line resolution.
09461 ;
09462 ; When in Long-Range Scan view the z-coordinate takes the place of the
09463 ; y-coordinate of the Front or Aft view. If the Long-Range Scan is damaged the
09464 ; passed pixel row number is treated randomly as a negative or positive value
09465 ; (mirror effect).
09466 ;
09467 ; INPUT
09468 ;
09469 ;   A = Pixel row number relative to the vertical screen center, always
09470 ;       positive. Used values are:
09471 ;     0..50 -> Regular values, pixel is onscreen
09472 ;     $FF   -> Pixel is offscreen
09473 ;
09474 ;   X = Position vector index. Used values are:
09475 ;     0..4  -> Position vector of a PLAYER space object
09476 ;     5..48 -> Position vector of a PLAYFIELD space object
09477
09478 L.PIXELROW      = $6D                   ; Saves relative pixel row number
09479
09480 SCREENROW       CMP #50                 ; If pixel is offscreen (A > 49)...
09481                 BCS SKIP233             ; ...return via initializing a new position vector
09482
09483                 STA L.PIXELROW          ; Save relative pixel row number
09484                 LDA #50                 ; If PLAYFIELD space object -> A := CENTERROW = 50
09485                 CPX #NUMSPCOBJ.PL       ;
09486                 BCS SKIP228             ;
09487                 ASL L.PIXELROW          ; If PLAYER space object -> Double pixel row number
09488                 LDA #122                ; If PLAYER space object ->    A := CENTERROW = 122
09489
09490 SKIP228         BIT SHIPVIEW            ; Skip if not in Long-Range Scan view
09491                 BVC SKIP230             ;
09492
09493                 BIT GCSTATLRS           ; Skip if Long-Range Scan OK
09494                 BPL SKIP229             ;
09495
09496                 BIT RANDOM              ; Long-Range Scan damaged...
09497                 BVC SKIP231             ; ...branch randomly to pixel row number calculation
09498                 BVS SKIP232             ; ...(mirror effect)
09499
09500 SKIP229         LDY ZPOSSIGN,X          ;
09501                 BNE SKIP231             ; Skip if z-coordinate pos. (Long-Range Scan view)
09502                 BEQ SKIP232             ; Skip if z-coordinate neg. (Long-Range Scan view)
09503
09504 SKIP230         LDY YPOSSIGN,X          ;
09505                 BEQ SKIP232             ; Skip if y-coordinate neg. (Front or Aft view)
09506
09507 SKIP231         SEC                     ; Pixel in upper screen half (z or y coordinate pos.)
09508                 INC L.PIXELROW          ;
09509                 SBC L.PIXELROW          ;
09510                 STA PIXELROWNEW,X       ; Pixel row  := CENTERROW - (rel. pixel row + 1)
09511                 RTS                     ; Return
09512
09513 SKIP232         CLC                     ; Pixel in lower screen half (y or z coordinate neg.)
09514                 ADC L.PIXELROW          ;
09515                 STA PIXELROWNEW,X       ; Pixel row := CENTERROW + relative pixel row
09516                 RTS                     ; Return
09517
09518 SKIP233         CPX #NUMSPCOBJ.PL       ; Space object is offscreen. If it is a...
09519                 BCS INITPOSVEC          ; ...PLAYFIELD space object -> New position vector
09520                 LDA #251                ; ...PLAYER space object    -> Push PLAYER offscreen
09521                 STA PIXELROWNEW,X       ;                              Why a value of 251 (?)
09522 SKIP234         RTS                     ; Return
09523
09524 ;*******************************************************************************
09525 ;*                                                                             *
09526 ;*                                 INITPOSVEC                                  *
09527 ;*                                                                             *
09528 ;*                Initialize position vector of a space object                 *
09529 ;*                                                                             *
09530 ;*******************************************************************************
09531
09532 ; DESCRIPTION
09533 ;
09534 ; Initializes the position vector of a space object.
09535 ;
09536 ; This subroutine executes the following steps:
09537 ;
09538 ; (1)  Set the pixel row and column number to an offscreen value (= 99).
09539 ;
09540 ; (2)  If the position vector represents an explosion fragment space object then
09541 ;      return code execution immediately. This avoids generating new explosion
09542 ;      fragment space objects. They are separately initialized in subroutine
09543 ;      COPYPOSVEC ($ACAF), which is called from subroutine INITEXPL ($AC6B).
09544 ;
09545 ; (3)  Assign default values (see below) to the position vector components
09546 ;      (coordinates) depending on our starship's view.
09547 ;
09548 ; Code execution continues into subroutine RNDINVXY ($B7BE) where x and y
09549 ; coordinates are inverted randomly.
09550 ;
09551 ; After passing through this and the next subroutine RNDINVXY ($B7BE) the
09552 ; components of a position vector (coordinates) are assigned to one of the
09553 ; following values depending on our starship's view:
09554 ;
09555 ; o   FRONT VIEW
09556 ;
09557 ;     +------------+---------------------------------------+
09558 ;     | Coordinate |                 Values                |
09559 ;     +------------+---------------------------------------+
09560 ;     |     x      |  -4095..+4095 (-($0***)..+$0***) <KM> |
09561 ;     |     y      |  -4095..+4095 (-($0***)..+$0***) <KM> | 
09562 ;     |     z      |  +3840..+4095 (          +$0F**) <KM> |
09563 ;     +------------+---------------------------------------+
09564 ;
09565 ; o   AFT VIEW
09566 ;
09567 ;     +------------+---------------------------------------+
09568 ;     | Coordinate |                 Values                |
09569 ;     +------------+---------------------------------------+ 
09570 ;     |     x      |  -3840..+3840 (-($0*00)..+$0*00) <KM> |
09571 ;     |     y      |  -3840..+3840 (-($0*00)..+$0*00) <KM> |
09572 ;     |     z      |  -3968.. -128 (-($0*80)        ) <KM> |
09573 ;     +------------+---------------------------------------+ 
09574 ;     Values of x, y, and z coordinates change in increments of 256.
09575 ;     Second digit of z-coordinate is -MAX(RNDY,RNDX), where
09576 ;     RNDY := RND($00..$0F), RNDX := RND($00..$0F).
09577 ;
09578 ; o   LONG-RANGE SCAN VIEW
09579 ;
09580 ;     +------------+---------------------------------------+
09581 ;     | Coordinate |                 Values                |
09582 ;     +------------+---------------------------------------+
09583 ;     |     x      | -65535..+65535 (-($****)..$****) <KM> |
09584 ;     |     y      |  -4095..+4095  (-($0***)..$0***) <KM> |
09585 ;     |     z      | -65535..+65535 (-($****)..$****) <KM> |
09586 ;     +------------+---------------------------------------+
09587 ;
09588 ; INPUT
09589 ;
09590 ;   X = Position vector index. Used values are: 0..48.
09591
09592 L.MAXRNDXY      = $6A                   ; Saves MAX(new y-coordinate (high byte), ...
09593                                         ;  ...new x-coordinate (high byte))
09594
09595 INITPOSVEC      LDA #99                 ; Init to offscreen pixel row and column numbers
09596                 STA PIXELROWNEW,X       ;
09597                 STA PIXELCOLUMN,X       ;
09598
09599                 CPX #NUMSPCOBJ.NORM     ; Return if pos vector is explosion frag space obj
09600                 BCS SKIP234             ; This avoids creating new explosion frag space objs
09601
09602                 LDA RANDOM              ; RNDY := RND($00..$0F)
09603                 AND #$0F                ;
09604                 STA L.MAXRNDXY          ; Save RNDY
09605                 STA YPOSHI,X            ; y-coordinate (high byte) := RNDY
09606
09607                 LDA RANDOM              ; RNDX := RND($00..$0F)
09608                 AND #$0F                ;
09609                 CMP L.MAXRNDXY          ;
09610                 BCC SKIP235             ;
09611                 STA L.MAXRNDXY          ; Save MAX(RNDY,RNDX)
09612 SKIP235         STA XPOSHI,X            ; x-coordinate (high byte) := RNDX
09613
09614                 LDA #$0F                ; z-coordinate (high byte) := $0F
09615                 STA ZPOSHI,X            ;
09616
09617                 LDA SHIPVIEW            ; z-coordinate (sign) := 1 or 0 (Front or Aft view)
09618                 EOR #$01                ;
09619                 AND #$01                ;
09620                 STA ZPOSSIGN,X          ;
09621                 BNE SKIP236             ; Skip if in Front or Long-Range Scan view
09622
09623                                         ; Aft view only:
09624                 STA XPOSLO,X            ; x-coordinate (low byte) := 0
09625                 STA YPOSLO,X            ; y-coordinate (low byte) := 0
09626                 SEC                     ; z-coordinate (high byte) := -MAX(RNDY,RNDX)
09627                 SBC L.MAXRNDXY          ;
09628                 STA ZPOSHI,X            ;
09629                 LDA #$80                ; z-coordinate (low byte) := $80
09630                 STA ZPOSLO,X            ;
09631
09632 SKIP236         BIT SHIPVIEW            ; If not in Long-Range Scan view skip to RNDINVXY
09633                 BVC RNDINVXY            ;
09634
09635                                         ; Long-Range Scan view only:
09636                 LDA RANDOM              ; x-coordinate (high byte) := RND($00..$FF)
09637                 STA XPOSHI,X            ;
09638                 LDA RANDOM              ; z-coordinate (high byte) := RND($00..$FF)
09639                 STA ZPOSHI,X            ;
09640                 AND #$01                ; Invert z-coordinate randomly
09641                 STA ZPOSSIGN,X          ;
09642
09643 ;*******************************************************************************
09644 ;*                                                                             *
09645 ;*                                  RNDINVXY                                   *
09646 ;*                                                                             *
09647 ;*         Randomly invert the x and y components of a position vector         *
09648 ;*                                                                             *
09649 ;*******************************************************************************
09650
09651 ; DESCRIPTION
09652 ;
09653 ; Randomly inverts the x and y components of a position vector (x and y
09654 ; coordinates). See also subroutine INITPOSVEC ($B764).
09655 ;
09656 ; INPUT
09657 ;
09658 ;   X = Position vector index. Used values are: 0..48.
09659
09660 RNDINVXY        LDA RANDOM              ; Set sign of y-coordinate randomly
09661                 AND #$01                ;
09662                 STA YPOSSIGN,X          ;
09663                 BNE SKIP237             ; Skip if sign positive
09664
09665                 SEC                     ; Sign negative -> Calc negative y-coordinate
09666                 SBC YPOSLO,X            ; (calculate two's-complement of 16-bit value)
09667                 STA YPOSLO,X            ;
09668                 LDA #0                  ;
09669                 SBC YPOSHI,X            ;
09670                 STA YPOSHI,X            ;
09671
09672 SKIP237         LDA RANDOM              ; Set sign of x-coordinate randomly
09673                 AND #$01                ;
09674                 STA XPOSSIGN,X          ;
09675                 BNE SKIP238             ; Skip if sign positive
09676
09677                 SEC                     ; Sign negative -> Calc negative x-coordinate
09678                 SBC XPOSLO,X            ; (calculate two's-complement of 16-bit value)
09679                 STA XPOSLO,X            ;
09680                 LDA #0                  ;
09681                 SBC XPOSHI,X            ;
09682                 STA XPOSHI,X            ;
09683 SKIP238         RTS                     ; Return
09684
09685 ;*******************************************************************************
09686 ;*                                                                             *
09687 ;*                                ISSURROUNDED                                 *
09688 ;*                                                                             *
09689 ;*               Check if a sector is surrounded by Zylon units                *
09690 ;*                                                                             *
09691 ;*******************************************************************************
09692
09693 ; DESCRIPTION
09694 ;
09695 ; Checks if a sector of the Galactic Chart is surrounded by Zylon units in the
09696 ; adjacent NORTH, EAST, SOUTH, and WEST sectors.
09697 ;
09698 ; INPUT
09699 ;
09700 ;   X = Sector of Galactic Chart. Used values are: $00..$7F with, for example,
09701 ;     $00 -> NORTHWEST corner sector
09702 ;     $0F -> NORTHEAST corner sector
09703 ;     $70 -> SOUTHWEST corner sector
09704 ;     $7F -> SOUTHWEST corner sector
09705 ;
09706 ; OUTPUT
09707 ;
09708 ;   A = Returns if the sector is surrounded by Zylon units in the adjacent
09709 ;       NORTH, EAST, SOUTH, and WEST sectors.
09710 ;       0 -> Sector is not surrounded
09711 ;     > 0 -> Sector is surrounded
09712
09713 ISSURROUNDED    LDA GCMEMMAP-1,X        ; Check WEST sector
09714                 BEQ SKIP239             ;
09715                 LDA GCMEMMAP+1,X        ; Check EAST sector
09716                 BEQ SKIP239             ;
09717                 LDA GCMEMMAP-16,X       ; Check NORTH sector
09718                 BEQ SKIP239             ;
09719                 LDA GCMEMMAP+16,X       ; Check SOUTH sector
09720 SKIP239         RTS                     ; Return
09721
09722 ;*******************************************************************************
09723 ;*                                                                             *
09724 ;*                                  UPDPANEL                                   *
09725 ;*                                                                             *
09726 ;*                        Update Control Panel Display                         *
09727 ;*                                                                             *
09728 ;*******************************************************************************
09729
09730 ; DESCRIPTION
09731 ;
09732 ; This subroutine executes the following steps: 
09733 ;
09734 ; (1)  Accelerate or decelerate our starship, update the VELOCITY readout
09735 ;
09736 ;      If the new velocity value is different from the current one either
09737 ;      increment or decrement the current velocity value toward the new one.
09738 ;
09739 ;      If the Engines are damaged or destroyed (and hyperwarp is not engaged)
09740 ;      then store a random value (less or equal than the current velocity) as
09741 ;      the current velocity.
09742 ;
09743 ;      Display the updated velocity by the VELOCITY readout of the Control Panel
09744 ;      Display.
09745 ;
09746 ; (2)  Update THETA, PHI, and RANGE readouts.
09747 ;
09748 ;      If the Attack Computer is working then display the x, y, and z
09749 ;      coordinates of the currently tracked space object as THETA, PHI, and
09750 ;      RANGE readout values of the Control Panel Display.
09751 ;
09752 ; (3)  Calculate overall energy consumption.
09753 ;
09754 ;      Add the overall energy consumption per game loop iteration to the energy
09755 ;      counter. This value is given in energy subunits (256 energy subunits = 1
09756 ;      energy unit displayed by the 4-digit ENERGY readout of the Console Panel
09757 ;      Display). It is the total of the following items:
09758 ;
09759 ;      (1)  8 energy subunits if the Shields are up
09760 ;
09761 ;      (2)  2 energy subunits if the Attack Computer is on
09762 ;
09763 ;      (3)  1 energy subunit of the life support system
09764 ;
09765 ;      (4)  Our starship's Engines energy drain rate (depending on its velocity)
09766 ;
09767 ;      If there is a carryover of the energy counter then decrement the ENERGY
09768 ;      readout of the Control Panel Display by one energy unit after code
09769 ;      execution has continued into subroutine DECENERGY ($B86F). 
09770
09771 ;*** Accelerate or decelerate our starship *************************************
09772 UPDPANEL        LDX VELOCITYLO          ; Skip if new velocity = current velocity
09773                 CPX NEWVELOCITY         ;
09774                 BEQ SKIP241             ;
09775
09776                 BCC SKIP240             ; In/decrement current velocity toward new velocity
09777                 DEC VELOCITYLO          ;
09778                 BCS SKIP242             ;
09779 SKIP240         INC VELOCITYLO          ;
09780
09781 SKIP241         LDA WARPSTATE           ; Skip if hyperwarp engaged
09782                 BNE SKIP242             ;
09783
09784                 BIT GCSTATENG           ; Skip if Engines are OK
09785                 BPL SKIP242             ;
09786
09787                 LDA NEWVELOCITY         ; Store RND(0..current velocity) to current velocity
09788                 AND RANDOM              ;
09789                 STA VELOCITYLO          ;
09790
09791 SKIP242         LDY #VELOCD1-PANELTXT-1 ; Update digits of VELOCITY readout
09792                 JSR SHOWDIGITS          ;
09793
09794 ;*** Display coordinates of tracked space object of Control Panel Display ******
09795                 BIT GCSTATCOM           ; Skip if Attack Computer damaged or destroyed
09796                 BMI SKIP243             ;
09797
09798                 LDA #$31                ; Update THETA readout (x-coordinate)
09799                 LDY #THETAC1-PANELTXT   ;
09800                 JSR SHOWCOORD           ;
09801
09802                 LDA #$62                ; Update PHI readout (y-coordinate)
09803                 LDY #PHIC1-PANELTXT     ;
09804                 JSR SHOWCOORD           ;
09805
09806                 LDA #$00                ; Update RANGE readout (z-coordinate)
09807                 LDY #RANGEC1-PANELTXT   ;
09808                 JSR SHOWCOORD           ;
09809
09810                 LDA RANGEC1+2           ; Hack to clear RANGE digit 3 when in hyperwarp:
09811                 STA RANGEC1+3           ; Copy RANGE digit 2 to digit 3
09812                 CMP #CCS.9+1            ; Skip if digit character > '9' (= 'infinity' char)
09813                 BCS SKIP243             ;
09814
09815                 LDX TRACKDIGIT          ; Get z-coordinate (low byte) of tracked space object
09816                 LDA ZPOSLO,X            ;
09817                 LSR A                   ; ...divide it by 16...
09818                 LSR A                   ;
09819                 LSR A                   ;
09820                 LSR A                   ;
09821                 TAX                     ;
09822                 LDA MAPTOBCD99,X        ; ...map value of $00..$0F to BCD value 0..9
09823                 STA RANGEC1+3           ; ...and store it to RANGE digit 3
09824
09825 ;*** Calculate overall energy consumption **************************************
09826 SKIP243         CLC                     ;
09827                 LDA ENERGYCNT           ; Load energy counter
09828                 ADC DRAINSHIELDS        ; Add energy drain rate of Shields
09829                 ADC DRAINENGINES        ; Add energy drain rate of our starship's Engines
09830                 ADC DRAINATTCOMP        ; Add energy drain rate of Attack Computer
09831                 ADC #$01                ; Add 1 energy subunit of life support system
09832                 CMP ENERGYCNT           ;
09833                 STA ENERGYCNT           ;
09834                 BCS SKIP246             ; Return if no energy counter carryover
09835
09836                 LDX #3                  ; Will decrement third energy digit
09837
09838 ;*******************************************************************************
09839 ;*                                                                             *
09840 ;*                                  DECENERGY                                  *
09841 ;*                                                                             *
09842 ;*                               Decrease energy                               *
09843 ;*                                                                             *
09844 ;*******************************************************************************
09845
09846 ; DESCRIPTION
09847 ;
09848 ; When not in demo mode, subtract energy from the 4-digit ENERGY readout of the
09849 ; Control Panel Display. If crossing a 100-energy-unit boundary during
09850 ; subtraction the score is decremented by one unit. If the energy is zero the
09851 ; game is over.
09852 ;
09853 ; INPUT
09854 ;
09855 ;   X = ENERGY readout digit to be decremented. Used values are:
09856 ;     1 -> Subtract 100 units from ENERGY readout
09857 ;     2 -> Subtract  10 units from ENERGY readout
09858 ;     3 -> Subtract   1 unit  from ENERGY readout
09859
09860 ;*** Display ENERGY readout ****************************************************
09861 DECENERGY       BIT ISDEMOMODE          ; Return if in demo mode
09862                 BVS SKIP246             ;
09863
09864                 DEC ENERGYD1,X          ; Decrement energy digit character
09865                 LDA ENERGYD1,X          ;
09866                 CMP #CCS.COL2!CCS.0     ;
09867                 BCS SKIP246             ; Return if digit character >= '0'
09868                 LDA #CCS.COL2!CCS.9     ;
09869                 STA ENERGYD1,X          ; Store digit character '9'
09870
09871 ;*** Decrement score when crossing a 100-energy-unit boundary while subtracting 
09872                 CPX #2                  ; Skip if no crossing of 100-energy-unit boundary
09873                 BNE SKIP245             ;
09874
09875                 LDA SCORE               ; SCORE := SCORE - 1
09876                 BNE SKIP244             ;
09877                 DEC SCORE+1             ;
09878 SKIP244         DEC SCORE               ;
09879
09880 SKIP245         DEX                     ;
09881                 BPL DECENERGY           ; Next digit
09882
09883 ;*** Energy is zero, game over *************************************************
09884                 LDX #CCS.SPC            ; Clear 4-digit ENERGY readout
09885                 TXA                     ;
09886                 LDY #3                  ;
09887 LOOP079         STA ENERGYD1,Y          ;
09888                 DEY                     ;
09889                 BPL LOOP079             ;
09890
09891                 JSR SETVIEW             ; Set Front view
09892
09893                 LDY #$31                ; Set title phrase "MISSION ABORTED ZERO ENERGY"
09894                 LDX #$04                ; Set mission bonus offset
09895                 JSR GAMEOVER            ; Game over
09896
09897 SKIP246         RTS                     ; Return
09898
09899 ;*******************************************************************************
09900 ;*                                                                             *
09901 ;*                                  SHOWCOORD                                  *
09902 ;*                                                                             *
09903 ;*  Display a position vector component (coordinate) in Control Panel Display  *
09904 ;*                                                                             *
09905 ;*******************************************************************************
09906
09907 ; DESCRIPTION
09908 ;
09909 ; Displays a position vector component (coordinate) by one of the THETA, PHI, or
09910 ; RANGE readouts of the Control Panel Display.
09911 ;
09912 ; Write the sign to the Control Panel Display, then map the high byte of the
09913 ; respective coordinate (x -> THETA, y -> PHI, z -> RANGE) to a BCD-value in
09914 ; 00..99. Code execution continues into subroutine SHOWDIGITS ($B8CD) where the
09915 ; digits are actually stored in the Control Panel Display.
09916 ;
09917 ; NOTE: If the digits of either the THETA or PHI readout are to be displayed and
09918 ; the x or y position vector component (high byte) is $FF then tweak the value
09919 ; to $FE. This avoids accessing table MAPTOBCD99 ($0EE9) with an index of $FF
09920 ; that would return the special value $EA. This value represents the CCS.INF
09921 ; ($0E) and CCS.SPC ($0A) characters (see comments in subroutine INITIALIZE
09922 ; ($B3BA)) that are displayed by the RANGE readout only.
09923 ;
09924 ; INPUT
09925 ;
09926 ;   A = Position vector component (coordinate) offset. Used values are: 
09927 ;     $00 -> z-coordinate
09928 ;     $31 -> x-coordinate
09929 ;     $62 -> y-coordinate
09930 ;
09931 ;   Y = Offset into the Control Panel Display memory map. Used values are:
09932 ;     $17 -> First character (sign) of THETA readout (x-coordinate of tracked
09933 ;            space object)
09934 ;     $1D -> First character (sign) of PHI readout   (y-coordinate of tracked
09935 ;            space object)
09936 ;     $23 -> First character (sign) of RANGE readout (z-coordinate of tracked
09937 ;            space object)
09938
09939 L.SIGNCHAR      = $6A                   ; Saves sign character
09940
09941 SHOWCOORD       CLC                     ; Add index of tracked space object...
09942                 ADC TRACKDIGIT          ; ...to position vector component offset
09943                 TAX                     ; Save position vector component index
09944
09945 ;*** Display sign in Control Panel Display *************************************
09946                 LDA #CCS.PLUS           ; Save '+' (CCS.PLUS) to sign character
09947                 STA L.SIGNCHAR          ;
09948
09949                 LDA ZPOSSIGN,X          ; Prep sign of coordinate
09950                 LSR A                   ;
09951                 LDA ZPOSHI,X            ; Prep coordinate (high byte)
09952                 BCS SKIP247             ; Skip if sign is positive
09953
09954                 EOR #$FF                ; Invert coordinate (high byte)
09955                 DEC L.SIGNCHAR          ; Change saved sign character to '-' (CCS.MINUS)
09956
09957 SKIP247         TAX                     ; Save coordinate (high byte)
09958                 LDA L.SIGNCHAR          ; Store sign character in Control Panel Display
09959                 STA PANELTXT,Y          ;
09960
09961 ;*** Get RANGE digits **********************************************************
09962                 TYA                     ; Skip if RANGE is to be displayed
09963                 AND #$10                ;
09964                 BEQ SHOWDIGITS          ;
09965
09966                 CPX #$FF                ; If coordinate (high byte) = $FF decrement value
09967                 BNE SHOWDIGITS          ; This avoids output of CCS.INFINITY in...
09968                 DEX                     ; ...THETA and PHI readouts
09969
09970 ;*******************************************************************************
09971 ;*                                                                             *
09972 ;*                                 SHOWDIGITS                                  *
09973 ;*                                                                             *
09974 ;*          Display a value by a readout of the Control Panel Display          *
09975 ;*                                                                             *
09976 ;*******************************************************************************
09977
09978 ; DESCRIPTION
09979 ;
09980 ; Converts a binary value in $00..$FF to a BCD-value in 0..99 and displays it as
09981 ; a 2-digit number in the Control Panel Display.
09982 ;
09983 ; INPUT
09984 ;
09985 ;   X = Value to be displayed as a 2-digit BCD-value. Used values are: $00..$FF.
09986 ;
09987 ;   Y = Offset into the Control Panel Display memory map relative to the first
09988 ;       character of the Control Panel Display (the 'V' of the VELOCITY
09989 ;       readout). Used values are: 
09990 ;     $01 -> Character before first digit of VELOCITY readout
09991 ;     $17 -> First character (sign) of THETA readout (x-coordinate of tracked
09992 ;            space object)
09993 ;     $1D -> First character (sign) of PHI readout   (y-coordinate of tracked
09994 ;            space object)
09995 ;     $23 -> First character (sign) of RANGE readout (z-coordinate of tracked
09996 ;            space object)
09997
09998 SHOWDIGITS      LDA MAPTOBCD99,X        ; Map binary value to BCD-value
09999                 TAX                     ;
10000                 AND #$0F                ;
10001                 STA PANELTXT+2,Y        ; Store 'ones' digit in Control Panel Display
10002                 TXA                     ;
10003                 LSR A                   ;
10004                 LSR A                   ;
10005                 LSR A                   ;
10006                 LSR A                   ;
10007                 STA PANELTXT+1,Y        ; Store 'tens' digit in Control Panel Display
10008                 RTS                     ; Return
10009
10010 ;*******************************************************************************
10011 ;*                                                                             *
10012 ;*                G A M E   D A T A   ( P A R T   2   O F   2 )                *
10013 ;*                                                                             *
10014 ;*******************************************************************************
10015
10016 ;*** Color register offsets of PLAYER0..4 **************************************
10017 PLCOLOROFFTAB   .BYTE 0                               ; PLAYER0
10018                 .BYTE 1                               ; PLAYER1
10019                 .BYTE 2                               ; PLAYER2
10020                 .BYTE 3                               ; PLAYER3
10021                 .BYTE 7                               ; PLAYER4
10022
10023 ;*** Shape table 1 (PLAYER2..4) ************************************************
10024 PLSHAP1TAB      .BYTE $00                             ; ........
10025                 .BYTE $18                             ; ...##...
10026                 .BYTE $3C                             ; ..####..
10027                 .BYTE $7E                             ; .######.
10028                 .BYTE $7E                             ; .######.
10029                 .BYTE $76                             ; .###.##.
10030                 .BYTE $F7                             ; ####.###
10031                 .BYTE $DF                             ; ##.#####
10032                 .BYTE $DF                             ; ##.#####
10033                 .BYTE $FF                             ; ########
10034                 .BYTE $FF                             ; ########
10035                 .BYTE $F7                             ; ####.###
10036                 .BYTE $76                             ; .###.##.
10037                 .BYTE $7E                             ; .######.
10038                 .BYTE $7E                             ; .######.
10039                 .BYTE $3C                             ; ..####..
10040                 .BYTE $18                             ; ...##...
10041                 .BYTE $10                             ; ...#....
10042                 .BYTE $38                             ; ..###...
10043                 .BYTE $7C                             ; .#####..
10044                 .BYTE $7C                             ; .#####..
10045                 .BYTE $FE                             ; #######.
10046                 .BYTE $DE                             ; ##.####.
10047                 .BYTE $DA                             ; ##.##.#.
10048                 .BYTE $FA                             ; #####.#.
10049                 .BYTE $EE                             ; ###.###.
10050                 .BYTE $EE                             ; ###.###.
10051                 .BYTE $7C                             ; .#####..
10052                 .BYTE $7C                             ; .#####..
10053                 .BYTE $38                             ; ..###...
10054                 .BYTE $10                             ; ...#....
10055                 .BYTE $18                             ; ...##...
10056                 .BYTE $3C                             ; ..####..
10057                 .BYTE $3C                             ; ..####..
10058                 .BYTE $7E                             ; .######.
10059                 .BYTE $6E                             ; .##.###.
10060                 .BYTE $7A                             ; .####.#.
10061                 .BYTE $7E                             ; .######.
10062                 .BYTE $76                             ; .###.##.
10063                 .BYTE $7E                             ; .######.
10064                 .BYTE $3C                             ; ..####..
10065                 .BYTE $3C                             ; ..####..
10066                 .BYTE $18                             ; ...##...
10067                 .BYTE $10                             ; ...#....
10068                 .BYTE $38                             ; ..###...
10069                 .BYTE $38                             ; ..###...
10070                 .BYTE $7C                             ; .#####..
10071                 .BYTE $74                             ; .###.#..
10072                 .BYTE $7C                             ; .#####..
10073                 .BYTE $6C                             ; .##.##..
10074                 .BYTE $38                             ; ..###...
10075                 .BYTE $38                             ; ..###...
10076                 .BYTE $10                             ; ...#....
10077                 .BYTE $10                             ; ...#....
10078                 .BYTE $18                             ; ...##...
10079                 .BYTE $3C                             ; ..####..
10080                 .BYTE $2C                             ; ..#.##..
10081                 .BYTE $3C                             ; ..####..
10082                 .BYTE $3C                             ; ..####..
10083                 .BYTE $18                             ; ...##...
10084                 .BYTE $08                             ; ....#...
10085                 .BYTE $10                             ; ...#....
10086                 .BYTE $38                             ; ..###...
10087                 .BYTE $38                             ; ..###...
10088                 .BYTE $28                             ; ..#.#...
10089                 .BYTE $38                             ; ..###...
10090                 .BYTE $10                             ; ...#....
10091                 .BYTE $3C                             ; ..####..
10092                 .BYTE $3C                             ; ..####..
10093                 .BYTE $24                             ; ..#..#..
10094                 .BYTE $3C                             ; ..####..
10095                 .BYTE $7E                             ; .######.
10096                 .BYTE $7E                             ; .######.
10097                 .BYTE $7E                             ; .######.
10098                 .BYTE $5A                             ; .#.##.#.
10099                 .BYTE $FF                             ; ########
10100                 .BYTE $FF                             ; ########
10101                 .BYTE $42                             ; .#....#.
10102                 .BYTE $42                             ; .#....#.
10103                 .BYTE $42                             ; .#....#.
10104                 .BYTE $42                             ; .#....#.
10105                 .BYTE $42                             ; .#....#.
10106                 .BYTE $42                             ; .#....#.
10107                 .BYTE $1C                             ; ...###..
10108                 .BYTE $1C                             ; ...###..
10109                 .BYTE $14                             ; ...#.#..
10110                 .BYTE $3E                             ; ..#####.
10111                 .BYTE $3E                             ; ..#####.
10112                 .BYTE $3E                             ; ..#####.
10113                 .BYTE $2A                             ; ..#.#.#.
10114                 .BYTE $7F                             ; .#######
10115                 .BYTE $7F                             ; .#######
10116                 .BYTE $22                             ; ..#...#.
10117                 .BYTE $22                             ; ..#...#.
10118                 .BYTE $22                             ; ..#...#.
10119                 .BYTE $22                             ; ..#...#.
10120                 .BYTE $22                             ; ..#...#.
10121                 .BYTE $18                             ; ...##...
10122                 .BYTE $18                             ; ...##...
10123                 .BYTE $3C                             ; ..####..
10124                 .BYTE $3C                             ; ..####..
10125                 .BYTE $3C                             ; ..####..
10126                 .BYTE $3C                             ; ..####..
10127                 .BYTE $7E                             ; .######.
10128                 .BYTE $24                             ; ..#..#..
10129                 .BYTE $24                             ; ..#..#..
10130                 .BYTE $24                             ; ..#..#..
10131                 .BYTE $24                             ; ..#..#..
10132                 .BYTE $10                             ; ...#....
10133                 .BYTE $10                             ; ...#....
10134                 .BYTE $38                             ; ..###...
10135                 .BYTE $38                             ; ..###...
10136                 .BYTE $38                             ; ..###...
10137                 .BYTE $7C                             ; .#####..
10138                 .BYTE $28                             ; ..#.#...
10139                 .BYTE $28                             ; ..#.#...
10140                 .BYTE $28                             ; ..#.#...
10141                 .BYTE $18                             ; ...##...
10142                 .BYTE $18                             ; ...##...
10143                 .BYTE $3C                             ; ..####..
10144                 .BYTE $18                             ; ...##...
10145                 .BYTE $18                             ; ...##...
10146                 .BYTE $10                             ; ...#....
10147                 .BYTE $10                             ; ...#....
10148                 .BYTE $38                             ; ..###...
10149                 .BYTE $10                             ; ...#....
10150                 .BYTE $18                             ; ...##...
10151                 .BYTE $7E                             ; .######.
10152                 .BYTE $FF                             ; ########
10153                 .BYTE $FF                             ; ########
10154                 .BYTE $FF                             ; ########
10155                 .BYTE $FF                             ; ########
10156                 .BYTE $FF                             ; ########
10157                 .BYTE $E7                             ; ###..###
10158                 .BYTE $E7                             ; ###..###
10159                 .BYTE $FF                             ; ########
10160                 .BYTE $FF                             ; ########
10161                 .BYTE $FF                             ; ########
10162                 .BYTE $FF                             ; ########
10163                 .BYTE $FF                             ; ########
10164                 .BYTE $7E                             ; .######.
10165                 .BYTE $7E                             ; .######.
10166                 .BYTE $00                             ; ........
10167                 .BYTE $18                             ; ...##...
10168                 .BYTE $3C                             ; ..####..
10169                 .BYTE $7E                             ; .######.
10170                 .BYTE $FF                             ; ########
10171                 .BYTE $FF                             ; ########
10172                 .BYTE $FF                             ; ########
10173                 .BYTE $E7                             ; ###..###
10174                 .BYTE $66                             ; .##..##.
10175                 .BYTE $FF                             ; ########
10176                 .BYTE $FF                             ; ########
10177                 .BYTE $FF                             ; ########
10178                 .BYTE $FF                             ; ########
10179                 .BYTE $7E                             ; .######.
10180                 .BYTE $7E                             ; .######.
10181                 .BYTE $00                             ; ........
10182                 .BYTE $18                             ; ...##...
10183                 .BYTE $3C                             ; ..####..
10184                 .BYTE $7E                             ; .######.
10185                 .BYTE $FF                             ; ########
10186                 .BYTE $FF                             ; ########
10187                 .BYTE $E7                             ; ###..###
10188                 .BYTE $66                             ; .##..##.
10189                 .BYTE $FF                             ; ########
10190                 .BYTE $FF                             ; ########
10191                 .BYTE $FF                             ; ########
10192                 .BYTE $FF                             ; ########
10193                 .BYTE $3C                             ; ..####..
10194                 .BYTE $18                             ; ...##...
10195                 .BYTE $3C                             ; ..####..
10196                 .BYTE $FF                             ; ########
10197                 .BYTE $FF                             ; ########
10198                 .BYTE $E7                             ; ###..###
10199                 .BYTE $66                             ; .##..##.
10200                 .BYTE $FF                             ; ########
10201                 .BYTE $FF                             ; ########
10202                 .BYTE $7E                             ; .######.
10203                 .BYTE $3C                             ; ..####..
10204                 .BYTE $00                             ; ........
10205                 .BYTE $18                             ; ...##...
10206                 .BYTE $3C                             ; ..####..
10207                 .BYTE $FF                             ; ########
10208                 .BYTE $FF                             ; ########
10209                 .BYTE $FF                             ; ########
10210                 .BYTE $3C                             ; ..####..
10211                 .BYTE $18                             ; ...##...
10212                 .BYTE $18                             ; ...##...
10213                 .BYTE $3C                             ; ..####..
10214                 .BYTE $FF                             ; ########
10215                 .BYTE $3C                             ; ..####..
10216                 .BYTE $18                             ; ...##...
10217                 .BYTE $28                             ; ..#.#...
10218                 .BYTE $28                             ; ..#.#...
10219                 .BYTE $28                             ; ..#.#...
10220                 .BYTE $28                             ; ..#.#...
10221                 .BYTE $EE                             ; ###.###.
10222                 .BYTE $00                             ; ........
10223                 .BYTE $00                             ; ........
10224                 .BYTE $EE                             ; ###.###.
10225                 .BYTE $28                             ; ..#.#...
10226                 .BYTE $28                             ; ..#.#...
10227                 .BYTE $28                             ; ..#.#...
10228                 .BYTE $28                             ; ..#.#...
10229
10230 ;*** Shape table 2 (PLAYER0..1) ************************************************
10231 PLSHAP2TAB      .BYTE $00                             ; ........
10232                 .BYTE $81                             ; #......#
10233                 .BYTE $81                             ; #......#
10234                 .BYTE $81                             ; #......#
10235                 .BYTE $81                             ; #......#
10236                 .BYTE $BD                             ; #.####.#
10237                 .BYTE $FF                             ; ########
10238                 .BYTE $FF                             ; ########
10239                 .BYTE $BD                             ; #.####.#
10240                 .BYTE $81                             ; #......#
10241                 .BYTE $81                             ; #......#
10242                 .BYTE $81                             ; #......#
10243                 .BYTE $81                             ; #......#
10244                 .BYTE $82                             ; #.....#.
10245                 .BYTE $82                             ; #.....#.
10246                 .BYTE $BA                             ; #.###.#.
10247                 .BYTE $FE                             ; #######.
10248                 .BYTE $FE                             ; #######.
10249                 .BYTE $BA                             ; #.###.#.
10250                 .BYTE $82                             ; #.....#.
10251                 .BYTE $82                             ; #.....#.
10252                 .BYTE $42                             ; .#....#.
10253                 .BYTE $5A                             ; .#.##.#.
10254                 .BYTE $7E                             ; .######.
10255                 .BYTE $7E                             ; .######.
10256                 .BYTE $5A                             ; .#.##.#.
10257                 .BYTE $42                             ; .#....#.
10258                 .BYTE $44                             ; .#...#..
10259                 .BYTE $54                             ; .#.#.#..
10260                 .BYTE $7C                             ; .#####..
10261                 .BYTE $7C                             ; .#####..
10262                 .BYTE $54                             ; .#.#.#..
10263                 .BYTE $44                             ; .#...#..
10264                 .BYTE $24                             ; ..#..#..
10265                 .BYTE $3C                             ; ..####..
10266                 .BYTE $3C                             ; ..####..
10267                 .BYTE $24                             ; ..#..#..
10268                 .BYTE $28                             ; ..#.#...
10269                 .BYTE $38                             ; ..###...
10270                 .BYTE $38                             ; ..###...
10271                 .BYTE $28                             ; ..#.#...
10272                 .BYTE $18                             ; ...##...
10273                 .BYTE $18                             ; ...##...
10274                 .BYTE $10                             ; ...#....
10275                 .BYTE $10                             ; ...#....
10276                 .BYTE $E0                             ; ###.....
10277                 .BYTE $F8                             ; #####...
10278                 .BYTE $F8                             ; #####...
10279                 .BYTE $FE                             ; #######.
10280                 .BYTE $57                             ; .#.#.###
10281                 .BYTE $FE                             ; #######.
10282                 .BYTE $F8                             ; #####...
10283                 .BYTE $F8                             ; #####...
10284                 .BYTE $C0                             ; ##......
10285                 .BYTE $C0                             ; ##......
10286                 .BYTE $F0                             ; ####....
10287                 .BYTE $C0                             ; ##......
10288                 .BYTE $F0                             ; ####....
10289                 .BYTE $F0                             ; ####....
10290                 .BYTE $FC                             ; ######..
10291                 .BYTE $BE                             ; #.#####.
10292                 .BYTE $FC                             ; ######..
10293                 .BYTE $F0                             ; ####....
10294                 .BYTE $80                             ; #.......
10295                 .BYTE $80                             ; #.......
10296                 .BYTE $C0                             ; ##......
10297                 .BYTE $C0                             ; ##......
10298                 .BYTE $F0                             ; ####....
10299                 .BYTE $BC                             ; #.####..
10300                 .BYTE $F0                             ; ####....
10301                 .BYTE $C0                             ; ##......
10302                 .BYTE $07                             ; .....###
10303                 .BYTE $1F                             ; ...#####
10304                 .BYTE $1F                             ; ...#####
10305                 .BYTE $7F                             ; .#######
10306                 .BYTE $EA                             ; ###.#.#.
10307                 .BYTE $7F                             ; .#######
10308                 .BYTE $1F                             ; ...#####
10309                 .BYTE $1F                             ; ...#####
10310                 .BYTE $03                             ; ......##
10311                 .BYTE $03                             ; ......##
10312                 .BYTE $0F                             ; ....####
10313                 .BYTE $03                             ; ......##
10314                 .BYTE $0F                             ; ....####
10315                 .BYTE $0F                             ; ....####
10316                 .BYTE $3F                             ; ..######
10317                 .BYTE $7D                             ; .#####.#
10318                 .BYTE $3F                             ; ..######
10319                 .BYTE $0F                             ; ....####
10320                 .BYTE $01                             ; .......#
10321                 .BYTE $01                             ; .......#
10322                 .BYTE $03                             ; ......##
10323                 .BYTE $03                             ; ......##
10324                 .BYTE $0F                             ; ....####
10325                 .BYTE $3D                             ; ..####.#
10326                 .BYTE $0F                             ; ....####
10327                 .BYTE $03                             ; ......##
10328                 .BYTE $18                             ; ...##...
10329                 .BYTE $3C                             ; ..####..
10330                 .BYTE $7E                             ; .######.
10331                 .BYTE $7E                             ; .######.
10332                 .BYTE $DB                             ; ##.##.##
10333                 .BYTE $C3                             ; ##....##
10334                 .BYTE $81                             ; #......#
10335                 .BYTE $81                             ; #......#
10336                 .BYTE $81                             ; #......#
10337                 .BYTE $10                             ; ...#....
10338                 .BYTE $38                             ; ..###...
10339                 .BYTE $7C                             ; .#####..
10340                 .BYTE $7C                             ; .#####..
10341                 .BYTE $D6                             ; ##.#.##.
10342                 .BYTE $C6                             ; ##...##.
10343                 .BYTE $82                             ; #.....#.
10344                 .BYTE $82                             ; #.....#.
10345                 .BYTE $18                             ; ...##...
10346                 .BYTE $3C                             ; ..####..
10347                 .BYTE $3C                             ; ..####..
10348                 .BYTE $66                             ; .##..##.
10349                 .BYTE $66                             ; .##..##.
10350                 .BYTE $42                             ; .#....#.
10351                 .BYTE $42                             ; .#....#.
10352                 .BYTE $10                             ; ...#....
10353                 .BYTE $38                             ; ..###...
10354                 .BYTE $38                             ; ..###...
10355                 .BYTE $6C                             ; .##.##..
10356                 .BYTE $44                             ; .#...#..
10357                 .BYTE $44                             ; .#...#..
10358                 .BYTE $18                             ; ...##...
10359                 .BYTE $3C                             ; ..####..
10360                 .BYTE $24                             ; ..#..#..
10361                 .BYTE $24                             ; ..#..#..
10362                 .BYTE $10                             ; ...#....
10363                 .BYTE $38                             ; ..###...
10364                 .BYTE $28                             ; ..#.#...
10365                 .BYTE $18                             ; ...##...
10366                 .BYTE $3C                             ; ..####..
10367                 .BYTE $7E                             ; .######.
10368                 .BYTE $FF                             ; ########
10369                 .BYTE $18                             ; ...##...
10370                 .BYTE $18                             ; ...##...
10371                 .BYTE $FF                             ; ########
10372                 .BYTE $7E                             ; .######.
10373                 .BYTE $3C                             ; ..####..
10374                 .BYTE $18                             ; ...##...
10375                 .BYTE $10                             ; ...#....
10376                 .BYTE $38                             ; ..###...
10377                 .BYTE $7C                             ; .#####..
10378                 .BYTE $FE                             ; #######.
10379                 .BYTE $38                             ; ..###...
10380                 .BYTE $38                             ; ..###...
10381                 .BYTE $FE                             ; #######.
10382                 .BYTE $7C                             ; .#####..
10383                 .BYTE $38                             ; ..###...
10384                 .BYTE $10                             ; ...#....
10385                 .BYTE $18                             ; ...##...
10386                 .BYTE $3C                             ; ..####..
10387                 .BYTE $7E                             ; .######.
10388                 .BYTE $18                             ; ...##...
10389                 .BYTE $7E                             ; .######.
10390                 .BYTE $3C                             ; ..####..
10391                 .BYTE $18                             ; ...##...
10392                 .BYTE $10                             ; ...#....
10393                 .BYTE $38                             ; ..###...
10394                 .BYTE $7C                             ; .#####..
10395                 .BYTE $10                             ; ...#....
10396                 .BYTE $7C                             ; .#####..
10397                 .BYTE $38                             ; ..###...
10398                 .BYTE $10                             ; ...#....
10399                 .BYTE $18                             ; ...##...
10400                 .BYTE $3C                             ; ..####..
10401                 .BYTE $18                             ; ...##...
10402                 .BYTE $3C                             ; ..####..
10403                 .BYTE $18                             ; ...##...
10404                 .BYTE $10                             ; ...#....
10405                 .BYTE $38                             ; ..###...
10406                 .BYTE $38                             ; ..###...
10407                 .BYTE $10                             ; ...#....
10408
10409 ;*** Display List fragments ****************************************************
10410 ;
10411 ; LOCAL VARIABLES
10412 PFMEM.C0R0      = PFMEM+0*40                          ; Start address of PLAYFIELD row 0
10413 PFMEM.C0R5      = PFMEM+5*40                          ; Start address of PLAYFIELD row 5
10414 PFMEM.C0R17     = PFMEM+17*40                         ; Start address of PLAYFIELD row 17
10415
10416 ;*** Display List fragment for Control Panel Display (bottom text window) ******
10417 DLSTFRAG        .BYTE $8D                             ; GR7 + DLI
10418                 .BYTE $00                             ; BLK1
10419                 .BYTE $46,<PANELTXT,>PANELTXT         ; GR1 @ PANELTXT
10420                 .BYTE $20                             ; BLK3
10421                 .BYTE $06                             ; GR1
10422                 .BYTE $00                             ; BLK1
10423
10424 ;*** Display List fragment for Galactic Chart view *****************************
10425 DLSTFRAGGC      .BYTE $01,<DLSTGC,>DLSTGC             ; JMP @ DLSTGC
10426
10427 ;*** Display List fragment for Long-Range Scan view ****************************
10428 DLSTFRAGLRS     .BYTE $00                             ; BLK1
10429                 .BYTE $00                             ; BLK1
10430                 .BYTE $46,<LRSHEADER,>LRSHEADER       ; GR1 @ LRSHEADER
10431                 .BYTE $4D,<PFMEM.C0R5,>PFMEM.C0R5     ; GR7 @ PFMEM.C0R5
10432
10433 ;*** Display List fragment for Aft view ****************************************
10434 DLSTFRAGAFT     .BYTE $00                             ; BLK1
10435                 .BYTE $00                             ; BLK1
10436                 .BYTE $46,<AFTHEADER,>AFTHEADER       ; GR1 @ AFTHEADER
10437                 .BYTE $4D,<PFMEM.C0R5,>PFMEM.C0R5     ; GR7 @ PFMEM.C0R5
10438
10439 ;*** Display List fragment for Front view and Title text line ******************
10440 DLSTFRAGFRONT   .BYTE $4D,<PFMEM.C0R0,>PFMEM.C0R0     ; GR7 @ PFMEM.C0R0
10441                 .BYTE $0D                             ; GR7
10442                 .BYTE $0D                             ; GR7
10443                 .BYTE $0D                             ; GR7
10444                 .BYTE $0D                             ; GR7
10445                 .BYTE $0D                             ; GR7
10446                 .BYTE $30                             ; BLK4
10447                 .BYTE $46,<TITLETXT,>TITLETXT         ; GR1 @ TITLETXT
10448                 .BYTE $4D,<PFMEM.C0R17,>PFMEM.C0R17   ; GR7 @ PFMEM.C0R17
10449
10450 ;*** Display List fragment offsets relative to DLSTFRAG ************************
10451 DLSTFRAGOFFTAB  .BYTE DLSTFRAGFRONT-DLSTFRAG          ; Front view
10452                 .BYTE DLSTFRAGAFT-DLSTFRAG            ; Aft view
10453                 .BYTE DLSTFRAGLRS-DLSTFRAG            ; Long-Range Scan view
10454                 .BYTE DLSTFRAGGC-DLSTFRAG             ; Galactic Chart view
10455
10456 ;*** 1-byte bit patterns for 4 pixels of same color for PLAYFIELD space objects 
10457 FOURCOLORPIXEL  .BYTE $FF                             ; COLOR3
10458                 .BYTE $FF                             ; COLOR3
10459                 .BYTE $FF                             ; COLOR3
10460                 .BYTE $FF                             ; COLOR3
10461                 .BYTE $AA                             ; COLOR2
10462                 .BYTE $FF                             ; COLOR3
10463                 .BYTE $AA                             ; COLOR2
10464                 .BYTE $FF                             ; COLOR3
10465                 .BYTE $AA                             ; COLOR2
10466                 .BYTE $AA                             ; COLOR2
10467                 .BYTE $AA                             ; COLOR2
10468                 .BYTE $FF                             ; COLOR3
10469                 .BYTE $AA                             ; COLOR2
10470                 .BYTE $AA                             ; COLOR2
10471                 .BYTE $AA                             ; COLOR2
10472                 .BYTE $AA                             ; COLOR2
10473                 .BYTE $AA                             ; COLOR2
10474                 .BYTE $AA                             ; COLOR2
10475                 .BYTE $AA                             ; COLOR2
10476                 .BYTE $55                             ; COLOR1
10477                 .BYTE $55                             ; COLOR1
10478                 .BYTE $AA                             ; COLOR2
10479                 .BYTE $55                             ; COLOR1
10480                 .BYTE $AA                             ; COLOR2
10481                 .BYTE $55                             ; COLOR1
10482                 .BYTE $55                             ; COLOR1
10483                 .BYTE $55                             ; COLOR1
10484                 .BYTE $AA                             ; COLOR2
10485                 .BYTE $55                             ; COLOR1
10486                 .BYTE $55                             ; COLOR1
10487                 .BYTE $55                             ; COLOR1
10488                 .BYTE $55                             ; COLOR1
10489
10490 ;*** Masks to filter 1 pixel (2 bits) from 4 pixels (1 byte of PLAYFIELD memory)
10491 PIXELMASKTAB    .BYTE $C0                             ; ##......
10492                 .BYTE $30                             ; ..##....
10493                 .BYTE $0C                             ; ....##..
10494                 .BYTE $03                             ; ......##
10495
10496 ;*** Velocity table ************************************************************
10497 VELOCITYTAB     .BYTE 0                               ; Speed 0 =   0 <KM/H>
10498                 .BYTE 1                               ; Speed 1 =   1 <KM/H>
10499                 .BYTE 2                               ; Speed 2 =   2 <KM/H>
10500                 .BYTE 4                               ; Speed 3 =   4 <KM/H>
10501                 .BYTE 8                               ; Speed 4 =   8 <KM/H>
10502                 .BYTE 16                              ; Speed 5 =  16 <KM/H>
10503                 .BYTE 32                              ; Speed 6 =  32 <KM/H>
10504                 .BYTE 64                              ; Speed 7 =  64 <KM/H>
10505                 .BYTE 96                              ; Speed 8 =  96 <KM/H>
10506                 .BYTE 112                             ; Speed 9 = 112 <KM/H>
10507
10508 ;*** Keyboard code lookup table ************************************************
10509 KEYTAB          .BYTE $F2                             ; '0'   - Speed 0
10510                 .BYTE $DF                             ; '1'   - Speed 1
10511                 .BYTE $DE                             ; '2'   - Speed 2
10512                 .BYTE $DA                             ; '3'   - Speed 3
10513                 .BYTE $D8                             ; '4'   - Speed 4
10514                 .BYTE $DD                             ; '5'   - Speed 5
10515                 .BYTE $DB                             ; '6'   - Speed 6
10516                 .BYTE $F3                             ; '7'   - Speed 7
10517                 .BYTE $F5                             ; '8'   - Speed 8
10518                 .BYTE $F0                             ; '9'   - Speed 9
10519                 .BYTE $F8                             ; 'F'   - Front view
10520                 .BYTE $FF                             ; 'A'   - Aft view
10521                 .BYTE $C0                             ; 'L'   - Long-Range Scan view
10522                 .BYTE $FD                             ; 'G'   - Galactic Chart view
10523                 .BYTE $ED                             ; 'T'   - Tracking on/off
10524                 .BYTE $FE                             ; 'S'   - Shields on/off
10525                 .BYTE $D2                             ; 'C'   - Attack Computer on/off
10526                 .BYTE $F9                             ; 'H'   - Hyperwarp
10527                 .BYTE $E5                             ; 'M'   - Manual Target Selector
10528                 .BYTE $CA                             ; 'P'   - Pause
10529                 .BYTE $E7                             ; 'INV' - Abort Mission
10530
10531 ;*** Engines energy drain rates per game loop iteration in energy subunits *****
10532 DRAINRATETAB    .BYTE 0                               ;
10533                 .BYTE 4                               ;
10534                 .BYTE 6                               ;
10535                 .BYTE 8                               ;
10536                 .BYTE 10                              ;
10537                 .BYTE 12                              ;
10538                 .BYTE 14                              ;
10539                 .BYTE 30                              ;
10540                 .BYTE 45                              ;
10541                 .BYTE 60                              ;
10542
10543 ;*** Hyperwarp energy depending on distance ************************************
10544 WARPENERGYTAB   .BYTE 10                              ; =  100 energy units
10545                 .BYTE 13                              ; =  130 energy units
10546                 .BYTE 16                              ; =  160 energy units
10547                 .BYTE 20                              ; =  200 energy units
10548                 .BYTE 23                              ; =  230 energy units
10549                 .BYTE 50                              ; =  500 energy units
10550                 .BYTE 70                              ; =  700 energy units
10551                 .BYTE 80                              ; =  800 energy units
10552                 .BYTE 90                              ; =  900 energy units
10553                 .BYTE 120                             ; = 1200 energy units
10554                 .BYTE 125                             ; = 1250 energy units
10555                 .BYTE 130                             ; = 1300 energy units
10556                 .BYTE 135                             ; = 1350 energy units
10557                 .BYTE 140                             ; = 1400 energy units
10558                 .BYTE 155                             ; = 1550 energy units
10559                 .BYTE 170                             ; = 1700 energy units
10560                 .BYTE 184                             ; = 1840 energy units
10561                 .BYTE 200                             ; = 2000 energy units
10562                 .BYTE 208                             ; = 2080 energy units
10563                 .BYTE 216                             ; = 2160 energy units
10564                 .BYTE 223                             ; = 2230 energy units
10565                 .BYTE 232                             ; = 2320 energy units
10566                 .BYTE 241                             ; = 2410 energy units
10567                 .BYTE 250                             ; = 2500 energy units
10568
10569 ;*** Joystick increments *******************************************************
10570 STICKINCTAB     .BYTE 0                               ; Centered
10571                 .BYTE 1                               ; Right or up
10572                 .BYTE -1                              ; Left or down
10573                 .BYTE 0                               ; Centered
10574
10575 ;*** 3-byte elements to draw cross hairs and Attack Computer Display ***********
10576 ;   Byte 1 : Pixel column number of line start
10577 ;   Byte 2 : Pixel row number of line start
10578 ;   Byte 3 : B7 = 0 -> Draw line to the right
10579 ;            B7 = 1 -> Draw line down
10580 ;            B6..0  -> Length of line in pixels. Possible values are: 0..127.
10581 ;
10582 ;                   #
10583 ;                   #                              4
10584 ;                   #                      ##############################
10585 ;                   #1                     #             #              #
10586 ;                   #                      #             #11            #
10587 ;                   #                      #             #              #
10588 ;                   #                      #5            #    8         #6
10589 ;                                          #      ###############       #
10590 ;                                          #      #             #       #
10591 ;         15                  16           #   7  #             #   10  #
10592 ; ###############       ###############    ########             #########
10593 ;                                          #      #12           #       #
10594 ;                                          #      #             #13     #
10595 ;                                          #      ###############       #
10596 ;                   #                      #         9   #              #
10597 ;                   #                      #             #              #
10598 ;                   #                      #             #14            #
10599 ;                   #                      #       3     #              #
10600 ;                   #2                     ##############################
10601 ;                   #
10602 ;                   #
10603 ;
10604 ;         Front/Aft Cross Hairs                Attack Computer Display
10605 ;
10606 ; LOCAL VARIABLES
10607 DOWN            = $80
10608 RIGHT           = $00
10609
10610 DRAWLINESTAB    .BYTE 80,40,DOWN!7                    ; Line 1
10611                 .BYTE 80,54,DOWN!7                    ; Line 2
10612
10613                 .BYTE 119,70,RIGHT!30                 ; Line 3
10614                 .BYTE 119,86,RIGHT!30                 ; Line 4
10615                 .BYTE 119,70,DOWN!17                  ; Line 5
10616                 .BYTE 148,70,DOWN!17                  ; Line 6
10617                 .BYTE 120,78,RIGHT!6                  ; Line 7
10618                 .BYTE 126,75,RIGHT!15                 ; Line 8
10619                 .BYTE 126,81,RIGHT!15                 ; Line 9
10620                 .BYTE 141,78,RIGHT!7                  ; Line 10
10621                 .BYTE 133,71,DOWN!4                   ; Line 11
10622                 .BYTE 126,76,DOWN!5                   ; Line 12
10623                 .BYTE 140,76,DOWN!5                   ; Line 13
10624                 .BYTE 133,82,DOWN!4                   ; Line 14
10625
10626                 .BYTE 62,50,RIGHT!15                  ; Line 15
10627                 .BYTE 84,50,RIGHT!15                  ; Line 16
10628                 .BYTE $FE                             ; End marker
10629
10630 ;*** 3-byte elements to draw our starship's shape in Long-Range Scan view ******
10631 ;
10632 ;   Line  17 18 19 20 21
10633 ;               ##
10634 ;               ##
10635 ;            ## ## ##
10636 ;         ## ## ## ## ##
10637 ;         ##    ##    ##
10638
10639                 .BYTE 78,53,DOWN!2                    ; Line 17
10640                 .BYTE 79,52,DOWN!2                    ; Line 18
10641                 .BYTE 80,50,DOWN!5                    ; Line 19
10642                 .BYTE 81,52,DOWN!2                    ; Line 20
10643                 .BYTE 82,53,DOWN!2                    ; Line 21
10644                 .BYTE $FE                             ; End marker
10645
10646 ;*** Initial x and y coordinates of a star during hyperwarp ********************
10647 ; The following two tables are used to determine the initial x and y coordinates
10648 ; (high byte) of a star during hyperwarp. An index in 0..3 picks both the x and
10649 ; y coordinate, thus 4 pairs of coordinates are possible:
10650 ;
10651 ; Y           +-------+----------------------------+----------------------------+
10652 ; ^           | Index |        x-coordinate        |        y-coordinate        |
10653 ; |           +-------+----------------------------+----------------------------+
10654 ; |.32.       |   0   | +1024..+1279 (+$04**) <KM> |  +512..+767  (+$02**) <KM> |
10655 ; |...1       |   1   | +1024..+1279 (+$04**) <KM> |  +768..+1023 (+$03**) <KM> |
10656 ; |...0       |   2   |  +768..+1023 (+$03**) <KM> | +1024..+1279 (+$04**) <KM> |
10657 ; |....       |   3   |  +512..+767  (+$02**) <KM> | +1024..+1279 (+$04**) <KM> |
10658 ; 0----->X    +-------+----------------------------+----------------------------+
10659
10660 ;*** Initial x-coordinate (high byte) of star in hyperwarp *********************
10661 WARPSTARXTAB    .BYTE $04                             ; +1024..+1279 (+$04**) <KM>
10662                 .BYTE $04                             ; +1024..+1279 (+$04**) <KM>
10663                 .BYTE $03                             ;  +768..+1023 (+$03**) <KM>
10664                 .BYTE $02                             ;  +512..+767  (+$02**) <KM>
10665
10666 ;*** Initial y-coordinate (high byte) of star in hyperwarp *********************
10667 WARPSTARYTAB    .BYTE $02                             ;  +512..+767  (+$02**) <KM>
10668                 .BYTE $03                             ;  +768..+1023 (+$03**) <KM>
10669                 .BYTE $04                             ; +1024..+1279 (+$04**) <KM>
10670                 .BYTE $04                             ; +1024..+1279 (+$04**) <KM>
10671
10672 ;*** Text of Control Panel Display (encoded in custom character set) ***********
10673 ; Row 1: "V:00 K:00 E:9999 T:0"
10674 ; Row 2: " O:-00 O:-00 R:-000 "
10675
10676 PANELTXTTAB     .BYTE CCS.V
10677                 .BYTE CCS.COLON
10678                 .BYTE CCS.0
10679                 .BYTE CCS.0
10680                 .BYTE CCS.SPC
10681                 .BYTE CCS.COL1!CCS.K
10682                 .BYTE CCS.COL1!CCS.COLON
10683                 .BYTE CCS.COL1!CCS.0
10684                 .BYTE CCS.COL1!CCS.0
10685                 .BYTE CCS.SPC
10686                 .BYTE CCS.COL2!CCS.E
10687                 .BYTE CCS.COL2!CCS.COLON
10688                 .BYTE CCS.COL2!CCS.9
10689                 .BYTE CCS.COL2!CCS.9
10690                 .BYTE CCS.COL2!CCS.9
10691                 .BYTE CCS.COL2!CCS.9
10692                 .BYTE CCS.SPC
10693                 .BYTE CCS.T
10694                 .BYTE CCS.COLON
10695                 .BYTE CCS.0
10696
10697                 .BYTE CCS.SPC
10698                 .BYTE CCS.THETA
10699                 .BYTE CCS.COLON
10700                 .BYTE CCS.MINUS
10701                 .BYTE CCS.0
10702                 .BYTE CCS.0
10703                 .BYTE CCS.SPC
10704                 .BYTE CCS.COL1!CCS.PHI
10705                 .BYTE CCS.COL1!CCS.COLON
10706                 .BYTE CCS.MINUS
10707                 .BYTE CCS.0
10708                 .BYTE CCS.0
10709                 .BYTE CCS.SPC
10710                 .BYTE CCS.COL2!CCS.R
10711                 .BYTE CCS.COL2!CCS.COLON
10712                 .BYTE CCS.MINUS
10713                 .BYTE CCS.0
10714                 .BYTE CCS.0
10715                 .BYTE CCS.0
10716                 .BYTE CCS.SPC
10717
10718 ;*** Text of Galactic Chart Panel Display **************************************
10719 ; Row 1: "WARP ENERGY:   0    "
10720 ; Row 2: "TARGETS:  DC:PESCLR "
10721 ; Row 3: "STAR DATE:00.00     "
10722
10723                 .BYTE ROM.W
10724                 .BYTE ROM.A
10725                 .BYTE ROM.R
10726                 .BYTE ROM.P
10727                 .BYTE ROM.SPC
10728                 .BYTE ROM.E
10729                 .BYTE ROM.N
10730                 .BYTE ROM.E
10731                 .BYTE ROM.R
10732                 .BYTE ROM.G
10733                 .BYTE ROM.Y
10734                 .BYTE ROM.COLON
10735                 .BYTE ROM.SPC
10736                 .BYTE ROM.SPC
10737                 .BYTE ROM.SPC
10738                 .BYTE ROM.0
10739                 .BYTE ROM.SPC
10740                 .BYTE ROM.SPC
10741                 .BYTE ROM.SPC
10742                 .BYTE ROM.SPC
10743
10744                 .BYTE CCS.COL2!ROM.T
10745                 .BYTE CCS.COL2!ROM.A
10746                 .BYTE CCS.COL2!ROM.R
10747                 .BYTE CCS.COL2!ROM.G
10748                 .BYTE CCS.COL2!ROM.E
10749                 .BYTE CCS.COL2!ROM.T
10750                 .BYTE CCS.COL2!ROM.S
10751                 .BYTE CCS.COL2!ROM.COLON
10752                 .BYTE ROM.SPC
10753                 .BYTE ROM.SPC
10754                 .BYTE ROM.D
10755                 .BYTE ROM.C
10756                 .BYTE ROM.COLON
10757                 .BYTE ROM.P
10758                 .BYTE ROM.E
10759                 .BYTE ROM.S
10760                 .BYTE ROM.C
10761                 .BYTE ROM.L
10762                 .BYTE ROM.R
10763                 .BYTE ROM.SPC
10764
10765                 .BYTE CCS.COL3!ROM.S
10766                 .BYTE CCS.COL3!ROM.T
10767                 .BYTE CCS.COL3!ROM.A
10768                 .BYTE CCS.COL3!ROM.R
10769                 .BYTE ROM.SPC
10770                 .BYTE CCS.COL3!ROM.D
10771                 .BYTE CCS.COL3!ROM.A
10772                 .BYTE CCS.COL3!ROM.T
10773                 .BYTE CCS.COL3!ROM.E
10774                 .BYTE CCS.COL3!ROM.COLON
10775                 .BYTE CCS.COL3!ROM.0
10776                 .BYTE CCS.COL3!ROM.0
10777                 .BYTE CCS.COL3!ROM.DOT
10778                 .BYTE CCS.COL3!ROM.0
10779                 .BYTE CCS.COL3!ROM.0
10780                 .BYTE ROM.SPC
10781                 .BYTE ROM.SPC
10782                 .BYTE ROM.SPC
10783                 .BYTE ROM.SPC
10784                 .BYTE ROM.SPC
10785
10786 ;*** Galactic Chart sector type table ******************************************
10787 SECTORTYPETAB   .BYTE $CF                             ; Starbase
10788                 .BYTE $04                             ; 4 Zylon ships
10789                 .BYTE $03                             ; 3 Zylon ships
10790                 .BYTE $02                             ; 1 or 2 Zylon ships
10791
10792 ;*** Phrase table **************************************************************
10793 ; Phrases consist of phrase tokens. These are bytes that encode words, segments
10794 ; (multiple words that fit into a single line of text), and how they are displayed.
10795 ;
10796 ; LOCAL VARIABLES
10797 EOP             = $40                                 ; End of phrase
10798 EOS             = $80                                 ; End of segment
10799 LONG            = $C0                                 ; Display title phrase for a long time
10800
10801                                                       ; Title Phrase Offset, Text
10802 PHRASETAB       .BYTE $00                             ; (unused)
10803                 .BYTE $05,$06,$02!EOP                 ; $01  "ATTACK COMPUTER ON"
10804                 .BYTE $05,$06,$03!EOP                 ; $04  "ATTACK COMPUTER OFF"
10805                 .BYTE $04,$02!EOP                     ; $07  "SHIELDS ON"
10806                 .BYTE $04,$03!EOP                     ; $09  "SHIELDS OFF"
10807                 .BYTE $06,$07,$02!EOP                 ; $0B  "COMPUTER TRACKING ON"
10808                 .BYTE $07,$03!EOP                     ; $0E  "TRACKING OFF"
10809                 .BYTE $08!EOP                         ; $10  "WHATS WRONG?"
10810                 .BYTE $09,$0A!EOP                     ; $11  "HYPERWARP ENGAGED"
10811                 .BYTE $0B,$0D!LONG                    ; $13  "STARBASE SURROUNDED"
10812                 .BYTE $0B,$0C!LONG                    ; $15  "STARBASE DESTROYED"
10813                 .BYTE $09,$0E!EOP                     ; $17  "HYPERWARP ABORTED"
10814                 .BYTE $09,$0F!EOP                     ; $19  "HYPERWARP COMPLETE"
10815                 .BYTE $10!LONG                        ; $1B  "HYPERSPACE"
10816                 .BYTE $11,$12!EOS                     ; $1C  "ORBIT ESTABLISHED"
10817                 .BYTE $16!EOP                         ; $1E  "STANDBY"
10818                 .BYTE $13,$0E!EOP                     ; $1F  "DOCKING ABORTED"
10819                 .BYTE $15,$0F!EOP                     ; $21  "TRANSFER COMPLETE"
10820                 .BYTE $38!EOS                         ; $23  " "
10821                 .BYTE $17!EOS                         ; $24  "STAR FLEET TO"
10822                 .BYTE $19!EOS                         ; $25  "ALL UNITS"
10823                 .BYTE $18!EOS                         ; $26  "STAR CRUISER 7"
10824                 .BYTE $0C!EOS                         ; $27  "DESTROYED"
10825                 .BYTE $1D!EOS                         ; $28  "BY ZYLON FIRE"
10826                 .BYTE $1E,$1F!EOS                     ; $29  "POSTHUMOUS RANK IS:"
10827                 .BYTE $FD                             ; $2B  "<PLACEHOLDER FOR RANK>"
10828                 .BYTE $25,$FC                         ; $2C  "CLASS <PLACEHOLDER FOR CLASS>"
10829                 .BYTE $38!EOP                         ; $2E  " "
10830                 .BYTE $1B!EOS                         ; $2F  "STAR RAIDERS"
10831                 .BYTE $20!EOP                         ; $30  "COPYRIGHT ATARI 1979"
10832                 .BYTE $38!EOS                         ; $31  " "
10833                 .BYTE $17!EOS                         ; $32  "STAR FLEET TO"
10834                 .BYTE $18!EOS                         ; $33  "STAR CRUISER 7"
10835                 .BYTE $1A,$0E!EOS                     ; $34  "MISSION ABORTED"
10836                 .BYTE $1C,$14!EOS                     ; $36  "ZERO ENERGY"
10837                 .BYTE $24,$1F!EOS                     ; $38  "NEW RANK IS"
10838                 .BYTE $FD                             ; $3A  "<PLACEHOLDER FOR RANK>"
10839                 .BYTE $25,$FC                         ; $3B  "CLASS <PLACEHOLDER FOR CLASS>"
10840                 .BYTE $27!EOS                         ; $3D  "REPORT TO BASE"
10841                 .BYTE $28!EOP                         ; $3E  "FOR TRAINING"
10842                 .BYTE $38!EOS                         ; $3F  " "
10843                 .BYTE $17!EOS                         ; $40  "STAR FLEET TO"
10844                 .BYTE $18!EOS                         ; $41  "STAR CRUISER 7"
10845                 .BYTE $1A,$0F!EOS                     ; $42  "MISSION COMPLETE"
10846                 .BYTE $24,$1F!EOS                     ; $44  "NEW RANK IS:"
10847                 .BYTE $FD                             ; $46  "<PLACEHOLDER FOR RANK>"
10848                 .BYTE $25,$FC                         ; $47  "CLASS <PLACEHOLDER FOR CLASS>"
10849                 .BYTE $26!EOP                         ; $49  "CONGRATULATIONS"
10850                 .BYTE $2C,$1A!EOP                     ; $4A  "NOVICE MISSION"
10851                 .BYTE $2E,$1A!EOP                     ; $4C  "PILOT MISSION"
10852                 .BYTE $31,$1A!EOP                     ; $4E  "WARRIOR MISSION"
10853                 .BYTE $33,$1A!EOP                     ; $50  "COMMANDER MISSION"
10854                 .BYTE $38!EOS                         ; $52  " "
10855                 .BYTE $34,$36!EOP                     ; $53  "DAMAGE CONTROL"
10856                 .BYTE $37,$35!EOS                     ; $55  "PHOTONS DAMAGED"
10857                 .BYTE $38!EOP                         ; $57  " "
10858                 .BYTE $37,$0C!EOS                     ; $58  "PHOTONS DESTROYED"
10859                 .BYTE $38!EOP                         ; $5A  " "
10860                 .BYTE $23,$35!EOS                     ; $5B  "ENGINES DAMAGED"
10861                 .BYTE $38!EOP                         ; $5D  " "
10862                 .BYTE $23,$0C!EOS                     ; $5E  "ENGINES DESTROYED"
10863                 .BYTE $38!EOP                         ; $60  " "
10864                 .BYTE $04,$35!EOS                     ; $61  "SHIELDS DAMAGED"
10865                 .BYTE $38!EOP                         ; $63  " "
10866                 .BYTE $04,$0C!EOS                     ; $64  "SHIELDS DESTROYED"
10867                 .BYTE $38!EOP                         ; $66  " "
10868                 .BYTE $06,$35!EOS                     ; $67  "COMPUTER DAMAGED"
10869                 .BYTE $38!EOP                         ; $69  " "
10870                 .BYTE $06,$0C!EOS                     ; $6A  "COMPUTER DESTROYED"
10871                 .BYTE $38!EOP                         ; $6C  " "
10872                 .BYTE $22!EOS                         ; $6D  "SECTOR SCAN"
10873                 .BYTE $35!EOP                         ; $6E  "DAMAGED"
10874                 .BYTE $22!EOS                         ; $6F  "SECTOR SCAN"
10875                 .BYTE $0C!EOP                         ; $70  "DESTROYED"
10876                 .BYTE $21!EOS                         ; $71  "SUB-SPACE RADIO"
10877                 .BYTE $35!EOP                         ; $72  "DAMAGED"
10878                 .BYTE $21!EOS                         ; $73  "SUB-SPACE RADIO"
10879                 .BYTE $0C!EOP                         ; $74  "DESTROYED"
10880                 .BYTE $01!LONG                        ; $75  "RED ALERT"
10881                 .BYTE $38!EOS                         ; $76  " "
10882                 .BYTE $17!EOS                         ; $77  "STAR FLEET TO"
10883                 .BYTE $18!EOS                         ; $78  "STAR CRUISER 7"
10884                 .BYTE $1A,$0E!EOS                     ; $79  "MISSION ABORTED"
10885                 .BYTE $24,$1F!EOS                     ; $7B  "NEW RANK IS:"
10886                 .BYTE $FD                             ; $7D  "<PLACEHOLDER FOR RANK>"
10887                 .BYTE $25,$FC                         ; $7E  "CLASS <PLACEHOLDER FOR CLASS>"
10888                 .BYTE $26!EOP                         ; $80  "CONGRATULATIONS"
10889
10890 ;*** Word table ****************************************************************
10891 ; Bit B7 of the first byte of a word is the end-of-word marker of the preceding
10892 ; word
10893 ;
10894 ; LOCAL VARIABLES
10895 EOW             = $80                                 ; End of word
10896
10897 WORDTAB         .BYTE EOW!$20,"    RED ALERT"         ; Word $01
10898                 .BYTE EOW!'O,"N"                      ; Word $02
10899                 .BYTE EOW!'O,"FF"                     ; Word $03
10900                 .BYTE EOW!'S,"HIELDS"                 ; Word $04
10901                 .BYTE EOW!'A,"TTACK"                  ; Word $05
10902                 .BYTE EOW!'C,"OMPUTER"                ; Word $06
10903                 .BYTE EOW!'T,"RACKING"                ; Word $07
10904                 .BYTE EOW!'W,"HATS WRONG?"            ; Word $08
10905                 .BYTE EOW!'H,"YPERWARP"               ; Word $09
10906                 .BYTE EOW!'E,"NGAGED"                 ; Word $0A
10907                 .BYTE EOW!'S,"TARBASE"                ; Word $0B
10908                 .BYTE EOW!'D,"ESTROYED"               ; Word $0C
10909                 .BYTE EOW!'S,"URROUNDED"              ; Word $0D
10910                 .BYTE EOW!'A,"BORTED"                 ; Word $0E
10911                 .BYTE EOW!'C,"OMPLETE"                ; Word $0F
10912                 .BYTE EOW!'H,"YPERSPACE"              ; Word $10
10913                 .BYTE EOW!'O,"RBIT"                   ; Word $11
10914                 .BYTE EOW!'E,"STABLISHED"             ; Word $12
10915                 .BYTE EOW!'D,"OCKING"                 ; Word $13
10916                 .BYTE EOW!'E,"NERGY"                  ; Word $14
10917                 .BYTE EOW!'T,"RANSFER"                ; Word $15
10918                 .BYTE EOW!'S,"TANDBY"                 ; Word $16
10919                 .BYTE EOW!'S,"TAR FLEET TO"           ; Word $17
10920                 .BYTE EOW!'S,"TAR CRUISER 7"          ; Word $18
10921                 .BYTE EOW!'A,"LL UNITS"               ; Word $19
10922                 .BYTE EOW!'M,"ISSION"                 ; Word $1A
10923                 .BYTE EOW!$20,"   STAR RAIDERS"       ; Word $1B
10924                 .BYTE EOW!'Z,"ERO"                    ; Word $1C
10925                 .BYTE EOW!'B,"Y ZYLON FIRE"           ; Word $1D
10926                 .BYTE EOW!'P,"OSTHUMOUS"              ; Word $1E
10927                 .BYTE EOW!'R,"ANK IS:"                ; Word $1F
10928                 .BYTE EOW!'C,"OPYRIGHT ATARI 1979"    ; Word $20
10929                 .BYTE EOW!'S,"UB-SPACE RADIO"         ; Word $21
10930                 .BYTE EOW!'S,"ECTOR SCAN"             ; Word $22
10931                 .BYTE EOW!'E,"NGINES"                 ; Word $23
10932                 .BYTE EOW!'N,"EW"                     ; Word $24
10933                 .BYTE EOW!'C,"LASS"                   ; Word $25
10934                 .BYTE EOW!'C,"ONGRATULATIONS"         ; Word $26
10935                 .BYTE EOW!'R,"EPORT TO BASE"          ; Word $27
10936                 .BYTE EOW!'F,"OR TRAINING"            ; Word $28
10937                 .BYTE EOW!'G,"ALACTIC COOK"           ; Word $29
10938                 .BYTE EOW!'G,"ARBAGE SCOW CAPTAIN"    ; Word $2A
10939                 .BYTE EOW!'R,"OOKIE"                  ; Word $2B
10940                 .BYTE EOW!'N,"OVICE"                  ; Word $2C
10941                 .BYTE EOW!'E,"NSIGN"                  ; Word $2D
10942                 .BYTE EOW!'P,"ILOT"                   ; Word $2E
10943                 .BYTE EOW!'A,"CE"                     ; Word $2F
10944                 .BYTE EOW!'L,"IEUTENANT"              ; Word $30
10945                 .BYTE EOW!'W,"ARRIOR"                 ; Word $31
10946                 .BYTE EOW!'C,"APTAIN"                 ; Word $32
10947                 .BYTE EOW!'C,"OMMANDER"               ; Word $33
10948                 .BYTE EOW!'D,"AMAGE"                  ; Word $34
10949                 .BYTE EOW!'D,"AMAGED"                 ; Word $35
10950                 .BYTE EOW!'C,"ONTROL"                 ; Word $36
10951                 .BYTE EOW!'P,"HOTONS"                 ; Word $37
10952                 .BYTE EOW!$20                         ; Word $38
10953                 .BYTE EOW!'S,"TAR COMMANDER"          ; Word $39
10954                 .BYTE EOW!$00                         ;
10955
10956 ;*** View modes ****************************************************************
10957 VIEWMODETAB     .BYTE $00                             ; Front view
10958                 .BYTE $01                             ; Aft view
10959                 .BYTE $40                             ; Long-Range Scan view
10960                 .BYTE $80                             ; Galactic Chart view
10961
10962 ;*** Title phrase offsets of "TRACKING OFF", "SHIELDS OFF", "COMPUTER OFF" *****
10963 MSGOFFTAB       .BYTE $0E                             ; "TRACKING OFF"
10964                 .BYTE $09                             ; "SHIELDS OFF"
10965                 .BYTE $04                             ; "COMPUTER OFF"
10966
10967 ;*** Masks to test if Tracking Computer, Shields, or Attack Computer are on ****
10968 MSGBITTAB       .BYTE $FF                             ; Mask Tracking Computer
10969                 .BYTE $08                             ; Mask Shields
10970                 .BYTE $02                             ; Mask Attack Computer
10971
10972 ;*** Title phrase offsets of "COMPUTER TRACKING ON", "SHIELDS ON", "COMPUTER ON"
10973 MSGONTAB        .BYTE $0B                             ; "COMPUTER TRACKING ON"
10974                 .BYTE $07                             ; "SHIELDS ON"
10975                 .BYTE $01                             ; "COMPUTER ON"
10976
10977 ;*** The following two tables encode the PLAYER shapes *************************
10978 ;
10979 ; PHOTON TORPEDO (shape type 0, data in shape table PLSHAP1TAB)
10980 ; Numbers at top indicate the shape table offset of the first and last shape row
10981 ;
10982 ; $01..$10  $11..$1E  $1F..$2A  $2B..$34  $35..$3C  $3D..$42  $75..$76  $7A..$7B
10983 ; ...##...  ...#....  ...##...  ...#....  ...#....  ...#....  ...##...  ...#....
10984 ; ..####..  ..###...  ..####..  ..###...  ...##...  ..###...  ...##...  ...#....
10985 ; .######.  .#####..  ..####..  ..###...  ..####..  ..###...
10986 ; .######.  .#####..  .######.  .#####..  ..#.##..  ..#.#...
10987 ; .###.##.  #######.  .##.###.  .###.#..  ..####..  ..###...
10988 ; ####.###  ##.####.  .####.#.  .#####..  ..####..  ...#....
10989 ; ##.#####  ##.##.#.  .######.  .##.##..  ...##...
10990 ; ##.#####  #####.#.  .###.##.  ..###...  ....#...
10991 ; ########  ###.###.  .######.  ..###...
10992 ; ########  ###.###.  ..####..  ...#....
10993 ; ####.###  .#####..  ..####..
10994 ; .###.##.  .#####..  ...##...
10995 ; .######.  ..###...
10996 ; .######.  ...#....
10997 ; ..####..
10998 ; ...##...
10999 ;
11000 ; ZYLON FIGHTER (shape type 1, data in shape table PLSHAP2TAB)
11001 ; Numbers at top indicate the shape table offset of the first and last shape row
11002 ;
11003 ; $01..$0C  $0D..$14  $15..$1A  $1B..$20  $21..$24  $25..$28  $29..$2A  $2B..$2C
11004 ; #......#  #.....#.  .#....#.  .#...#..  ..#..#..  ..#.#...  ...##...  ...#....
11005 ; #......#  #.....#.  .#.##.#.  .#.#.#..  ..####..  ..###...  ...##...  ...#....
11006 ; #......#  #.###.#.  .######.  .#####..  ..####..  ..###...
11007 ; #......#  #######.  .######.  .#####..  ..#..#..  ..#.#...
11008 ; #.####.#  #######.  .#.##.#.  .#.#.#..
11009 ; ########  #.###.#.  .#....#.  .#...#..
11010 ; ########  #.....#.
11011 ; #.####.#  #.....#.
11012 ; #......#
11013 ; #......#
11014 ; #......#
11015 ; #......#
11016 ;
11017 ; STARBASE RIGHT (shape type 2, data in shape table PLSHAP2TAB)
11018 ; Numbers at top indicate the shape table offset of the first and last shape row
11019 ;
11020 ; $2D..$36  $38..$40  $41..$46  $36..$38  $36       $00       $00       $00
11021 ; ###.....  ##......  ##......  ##......  ##......  ........  ........  ........
11022 ; #####...  ####....  ##......  ####....
11023 ; #####...  ####....  ####....  ##......
11024 ; #######.  ######..  #.####..
11025 ;  #.#.###  #.#####.  ####....
11026 ; #######.  ######..  ##......
11027 ; #####...  ####....
11028 ; #####...  #.......
11029 ; ##......  #.......
11030 ; ##......
11031 ;
11032 ; STARBASE CENTER (shape type 3, data in shape table PLSHAP1TAB)
11033 ; Numbers at top indicate the shape table offset of the first and last shape row
11034 ;
11035 ; $7E..$8D  $8E..$9C  $9D..$A9  $AA..$B3  $B4..$BB  $BC..$C0  $7B..$7D  $7A..$7B
11036 ; ...##...  ........  ........  ...##...  ........  ...##...  ...#....  ...#....
11037 ; .######.  ...##...  ...##...  ..####..  ...##...  ..####..  ..###...  ...#....
11038 ; ########  ..####..  ..####..  ########  ..####..  ########  ...#....
11039 ; ########  .######.  .######.  ########  ########  ..####..
11040 ; ########  ########  ########  ###..###  ########  ...##...
11041 ; ########  ########  ########  .##..##.  ########
11042 ; ########  ########  ###..###  ########  ..####..
11043 ; ###..###  ###..###  .##..##.  ########  ...##...
11044 ; ###..###  .##..##.  ########  .######.
11045 ; ########  ########  ########  ..####..
11046 ; ########  ########  ########
11047 ; ########  ########  ########
11048 ; ########  ########  ..####..
11049 ; ########  .######.
11050 ; .######.  .######.
11051 ; .######.
11052 ;
11053 ; STARBASE LEFT (shape type 4, data in shape table PLSHAP2TAB)
11054 ; Numbers at top indicate the shape table offset of the first and last shape row
11055 ;
11056 ; $47..$50  $52..$5A  $5B..$60  $50..$52  $50       $00       $00       $00
11057 ; .....###  ......##  ......##  ......##  ......##  ........  ........  ........
11058 ; ...#####  ....####  ......##  ....####
11059 ; ...#####  ....####  ....####  ......##
11060 ; .#######  ..######  ..####.#
11061 ; ###.#.#.  .#####.#  ....####
11062 ; .#######  ..######  ......##
11063 ; ...#####  ....####
11064 ; ...#####  .......#
11065 ; ......##  .......#
11066 ; ......##
11067 ;
11068 ; TRANSFER VESSEL (shape type 5, data in shape table PLSHAP1TAB)
11069 ; Numbers at top indicate the shape table offset of the first and last shape row
11070 ;
11071 ; $43..$52  $53..$60  $61..$6B  $6C..$74  $75..$79  $7A..$7D  $75..$76  $7A..$7B
11072 ; ..####..  ...###..  ...##...  ...#....  ...##...  ...#....  ...##...  ...#....
11073 ; ..####..  ...###..  ...##...  ...#....  ...##...  ...#....  ...##...  ...#....
11074 ; ..#..#..  ...#.#..  ..####..  ..###...  ..####..  ..###...
11075 ; ..####..  ..#####.  ..####..  ..###...  ...##...  ...#....
11076 ; .######.  ..#####.  ..####..  ..###...  ...##...
11077 ; .######.  ..#####.  ..####..  .#####..
11078 ; .######.  ..#.#.#.  .######.  ..#.#...
11079 ; .#.##.#.  .#######  ..#..#..  ..#.#...
11080 ; ########  .#######  ..#..#..  ..#.#...
11081 ; ########  ..#...#.  ..#..#..
11082 ; .#....#.  ..#...#.  ..#..#..
11083 ; .#....#.  ..#...#.
11084 ; .#....#.  ..#...#.
11085 ; .#....#.  ..#...#.
11086 ; .#....#.
11087 ; .#....#.
11088 ;
11089 ; METEOR (shape type 6, data in shape table PLSHAP1TAB)
11090 ; Numbers at top indicate the shape table offset of the first and last shape row
11091 ;
11092 ; $01..$10  $11..$1E  $1F..$2A  $2B..$34  $35..$3C  $3D..$42  $75..$76  $7A..$7B
11093 ; ...##...  ...#....  ...##...  ...#....  ...#....  ...#....  ...##...  ...#....
11094 ; ..####..  ..###...  ..####..  ..###...  ...##...  ..###...  ...##...  ...#....
11095 ; .######.  .#####..  ..####..  ..###...  ..####..  ..###...
11096 ; .######.  .#####..  .######.  .#####..  ..#.##..  ..#.#...
11097 ; .###.##.  #######.  .##.###.  .###.#..  ..####..  ..###...
11098 ; ####.###  ##.####.  .####.#.  .#####..  ..####..  ...#....
11099 ; ##.#####  ##.##.#.  .######.  .##.##..  ...##...
11100 ; ##.#####  #####.#.  .###.##.  ..###...  ....#...
11101 ; ########  ###.###.  .######.  ..###...
11102 ; ########  ###.###.  ..####..  ...#....
11103 ; ####.###  .#####..  ..####..
11104 ; .###.##.  .#####..  ...##...
11105 ; .######.  ..###...
11106 ; .######.  ...#....
11107 ; ..####..
11108 ; ...##...
11109 ;
11110 ; ZYLON CRUISER (shape type 7, data in shape table PLSHAP2TAB)
11111 ; Numbers at top indicate the shape table offset of the first and last shape row
11112 ;
11113 ; $61..$69  $6A..$71  $72..$78  $79..$7E  $7F..$82  $83..$85  $29..$2A  $2B..$2C
11114 ; ...##...  ...#....  ...##...  ...#....  ...##...  ...#....  ...##...  ...#....
11115 ; ..####..  ..###...  ..####..  ..###...  ..####..  ..###...  ...##...  ...#....
11116 ; .######.  .#####..  ..####..  ..###...  ..#..#..  ..#.#...
11117 ; .######.  .#####..  .##..##.  .##.##..  ..#..#..
11118 ; ##.##.##  ##.#.##.  .##..##.  .#...#..
11119 ; ##....##  ##...##.  .#....#.  .#...#..
11120 ; #......#  #.....#.  .#....#.
11121 ; #......#  #.....#.
11122 ; #......#
11123 ;
11124 ; ZYLON BASESTAR (shape type 8, data in shape table PLSHAP2TAB)
11125 ; Numbers at top indicate the shape table offset of the first and last shape row
11126 ;
11127 ; $86..$8F  $90..$99  $9A..$A0  $A1..$A7  $A8..$AC  $AD..$B0  $29..$2A  $2B..$2C
11128 ; ...##...  ...#....  ...##...  ...#....  ...##...  ...#....  ...##...  ...#....
11129 ; ..####..  ..###...  ..####..  ..###...  ..####..  ..###...  ...##...  ...#....
11130 ; .######.  .#####..  .######.  .#####..  ...##...  ..###...
11131 ; ########  #######.  ...##...  ...#....  ..####..  ...#....
11132 ; ...##...  ..###...  .######.  .#####..  ...##...
11133 ; ...##...  ..###...  ..####..  ..###...
11134 ; ########  #######.  ...##...  ...#....
11135 ; .######.  .#####..
11136 ; ..####..  ..###...
11137 ; ...##...  ...#....
11138 ;
11139 ; HYPERWARP TARGET MARKER (shape type 9, data in shape table PLSHAP1TAB)
11140 ; Numbers at top indicate the shape table offset of the first and last shape row
11141 ;
11142 ; $C1..$CC  $C1..$CC  $C1..$CC  $C1..$CC  $C1..$CC  $C1..$CC  $75..$76  $C1..$CC
11143 ; ..#.#...  ..#.#...  ..#.#...  ..#.#...  ..#.#...  ..#.#...  ...##...  ..#.#...
11144 ; ..#.#...  ..#.#...  ..#.#...  ..#.#...  ..#.#...  ..#.#...  ...##...  ..#.#...
11145 ; ..#.#...  ..#.#...  ..#.#...  ..#.#...  ..#.#...  ..#.#...            ..#.#...
11146 ; ..#.#...  ..#.#...  ..#.#...  ..#.#...  ..#.#...  ..#.#...            ..#.#...
11147 ; ###.###.  ###.###.  ###.###.  ###.###.  ###.###.  ###.###.            ###.###.
11148 ; ........  ........  ........  ........  ........  ........            ........
11149 ; ........  ........  ........  ........  ........  ........            ........
11150 ; ###.###.  ###.###.  ###.###.  ###.###.  ###.###.  ###.###.            ###.###.
11151 ; ..#.#...  ..#.#...  ..#.#...  ..#.#...  ..#.#...  ..#.#...            ..#.#...
11152 ; ..#.#...  ..#.#...  ..#.#...  ..#.#...  ..#.#...  ..#.#...            ..#.#...
11153 ; ..#.#...  ..#.#...  ..#.#...  ..#.#...  ..#.#...  ..#.#...            ..#.#...
11154 ; ..#.#...  ..#.#...  ..#.#...  ..#.#...  ..#.#...  ..#.#...            ..#.#...
11155
11156 ;*** Shape type 0..9 offset table (10 shape cell offsets of shape type...) *****
11157 PLSHAPOFFTAB    .BYTE $01,$11,$1F,$2B,$35,$3D,$75,$7A ; ...0 into PLSHAP1TAB
11158                 .BYTE $01,$0D,$15,$1B,$21,$25,$29,$2B ; ...1 into PLSHAP2TAB
11159                 .BYTE $2D,$38,$41,$36,$36,$00,$00,$00 ; ...2 into PLSHAP2TAB
11160                 .BYTE $7E,$8E,$9D,$AA,$B4,$BC,$7B,$7A ; ...3 into PLSHAP1TAB
11161                 .BYTE $47,$52,$5B,$50,$50,$00,$00,$00 ; ...4 into PLSHAP2TAB
11162                 .BYTE $43,$53,$61,$6C,$75,$7A,$75,$7A ; ...5 into PLSHAP1TAB
11163                 .BYTE $01,$11,$1F,$2B,$35,$3D,$75,$7A ; ...6 into PLSHAP1TAB
11164                 .BYTE $61,$6A,$72,$79,$7F,$83,$29,$2B ; ...7 into PLSHAP2TAB
11165                 .BYTE $86,$90,$9A,$A1,$A8,$AD,$29,$2B ; ...8 into PLSHAP2TAB
11166                 .BYTE $C1,$C1,$C1,$C1,$C1,$C1,$75,$C1 ; ...9 into PLSHAP1TAB
11167
11168 ;*** Shape type 0..9 height table (10 shape cell heights of shape type...) *****
11169 PLSHAPHEIGHTTAB .BYTE $0F,$0D,$0B,$09,$07,$05,$01,$01 ; ...0
11170                 .BYTE $0B,$07,$05,$05,$03,$03,$01,$01 ; ...1
11171                 .BYTE $09,$08,$05,$02,$00,$00,$00,$00 ; ...2
11172                 .BYTE $0F,$0E,$0C,$09,$07,$04,$02,$01 ; ...3
11173                 .BYTE $09,$08,$05,$02,$00,$00,$00,$00 ; ...4
11174                 .BYTE $0F,$0D,$0A,$08,$04,$03,$01,$01 ; ...5
11175                 .BYTE $0F,$0D,$0B,$09,$07,$05,$01,$01 ; ...6
11176                 .BYTE $08,$07,$06,$05,$03,$02,$01,$01 ; ...7
11177                 .BYTE $09,$09,$06,$06,$04,$03,$01,$01 ; ...8
11178                 .BYTE $0B,$0B,$0B,$0B,$0B,$0B,$01,$0B ; ...9
11179
11180 ;*** Keyboard codes to switch to Front or Aft view when Tracking Computer is on 
11181 TRACKKEYSTAB    .BYTE $F8                             ; 'F' - Front view
11182                 .BYTE $FF                             ; 'A' - Aft view
11183
11184 ;*** Galactic Chart sector character codes (encoded in custom character set) ***
11185 SECTORCHARTAB   .BYTE CCS.BORDERSW                    ; Empty sector
11186                 .BYTE CCS.2ZYLONS                     ; Sector contains 1 Zylon ship
11187                 .BYTE CCS.2ZYLONS                     ; Sector contains 2 Zylon ships
11188                 .BYTE CCS.3ZYLONS                     ; Sector contains 3 Zylon ships
11189                 .BYTE CCS.4ZYLONS                     ; Sector contains 4 Zylon ships
11190                 .BYTE CCS.STARBASE                    ; Sector contains starbase
11191
11192 ;*** Mask to limit veer-off velocity of Hyperwarp Target Marker in hyperwarp ***
11193 VEERMASKTAB     .BYTE NEG!31                          ;  -31..+31  <KM/H> (unused)
11194                 .BYTE NEG!63                          ;  -63..+63  <KM/H> PILOT mission
11195                 .BYTE NEG!95                          ;  -95..+95  <KM/H> WARRIOR mission
11196                 .BYTE NEG!127                         ; -127..+127 <KM/H> COMMANDER mission
11197
11198 ;*** Horizontal PLAYER offsets for PLAYER0..1 (STARBASE LEFT, STARBASE RIGHT) **
11199 PLSTARBAOFFTAB  .BYTE -8                              ; -8 Player/Missile pixels
11200                 .BYTE 8                               ; +8 Player/Missile pixels
11201
11202 ;*** Mission bonus table *******************************************************
11203 BONUSTAB        .BYTE 80                              ; Mission complete   NOVICE mission
11204                 .BYTE 76                              ; Mission complete   PILOT mission
11205                 .BYTE 60                              ; Mission complete   WARRIOR mission
11206                 .BYTE 111                             ; Mission complete   COMMANDER mission
11207
11208                 .BYTE 60                              ; Mission aborted    NOVICE mission
11209                 .BYTE 60                              ; Mission aborted    PILOT mission
11210                 .BYTE 50                              ; Mission aborted    WARRIOR mission
11211                 .BYTE 100                             ; Mission aborted    COMMANDER mission
11212
11213                 .BYTE 40                              ; Starship destroyed NOVICE mission
11214                 .BYTE 50                              ; Starship destroyed PILOT mission
11215                 .BYTE 40                              ; Starship destroyed WARRIOR mission
11216                 .BYTE 90                              ; Starship destroyed COMMANDER mission
11217
11218 ;*** Title phrase offsets of scored class rank *********************************
11219 RANKTAB         .BYTE $29!EOS                         ; "GALACTIC COOK"
11220                 .BYTE $2A!EOS                         ; "GARBAGE SCOW CAPTAIN"
11221                 .BYTE $2A!EOS                         ; "GARBAGE SCOW CAPTAIN"
11222                 .BYTE $2B!EOS                         ; "ROOKIE"
11223                 .BYTE $2B!EOS                         ; "ROOKIE"
11224                 .BYTE $2C!EOS                         ; "NOVICE"
11225                 .BYTE $2C!EOS                         ; "NOVICE"
11226                 .BYTE $2D!EOS                         ; "ENSIGN"
11227                 .BYTE $2D!EOS                         ; "ENSIGN"
11228                 .BYTE $2E!EOS                         ; "PILOT"
11229                 .BYTE $2E!EOS                         ; "PILOT"
11230                 .BYTE $2F!EOS                         ; "ACE"
11231                 .BYTE $30!EOS                         ; "LIEUTENANT"
11232                 .BYTE $31!EOS                         ; "WARRIOR"
11233                 .BYTE $32!EOS                         ; "CAPTAIN"
11234                 .BYTE $33!EOS                         ; "COMMANDER"
11235                 .BYTE $33!EOS                         ; "COMMANDER"
11236                 .BYTE $39!EOS                         ; "STAR COMMANDER"
11237                 .BYTE $39!EOS                         ; "STAR COMMANDER"
11238
11239 ;*** Scored class number table *************************************************
11240 CLASSTAB        .BYTE CCS.COL2!ROM.5                  ; Class 5
11241                 .BYTE CCS.COL2!ROM.5                  ; Class 5
11242                 .BYTE CCS.COL2!ROM.5                  ; Class 5
11243                 .BYTE CCS.COL2!ROM.4                  ; Class 4
11244                 .BYTE CCS.COL2!ROM.4                  ; Class 4
11245                 .BYTE CCS.COL2!ROM.4                  ; Class 4
11246                 .BYTE CCS.COL2!ROM.4                  ; Class 4
11247                 .BYTE CCS.COL2!ROM.3                  ; Class 3
11248                 .BYTE CCS.COL2!ROM.3                  ; Class 3
11249                 .BYTE CCS.COL2!ROM.3                  ; Class 3
11250                 .BYTE CCS.COL2!ROM.2                  ; Class 2
11251                 .BYTE CCS.COL2!ROM.2                  ; Class 2
11252                 .BYTE CCS.COL2!ROM.2                  ; Class 2
11253                 .BYTE CCS.COL2!ROM.1                  ; Class 1
11254                 .BYTE CCS.COL2!ROM.1                  ; Class 1
11255                 .BYTE CCS.COL2!ROM.1                  ; Class 1
11256
11257 ;*** Title phrase offsets of mission level *************************************
11258 MISSIONPHRTAB   .BYTE $4A                             ; "NOVICE MISSION"
11259                 .BYTE $4C                             ; "PILOT MISSION"
11260                 .BYTE $4E                             ; "WARRIOR MISSION"
11261                 .BYTE $50                             ; "COMMANDER MISSION"
11262
11263 ;*** Damage probability of subsystems depending on mission level ***************
11264 DAMAGEPROBTAB   .BYTE 0                               ;  0% (  0:256) NOVICE mission
11265                 .BYTE 80                              ; 31% ( 80:256) PILOT mission
11266                 .BYTE 180                             ; 70% (180:256) WARRIOR mission
11267                 .BYTE 254                             ; 99% (254:256) COMMANDER mission
11268
11269 ;*** Title phrase offsets of damaged subsystems ********************************
11270 DAMAGEPHRTAB    .BYTE $55                             ; "PHOTON TORPEDOS DAMAGED"
11271                 .BYTE $5B                             ; "ENGINES DAMAGED"
11272                 .BYTE $61                             ; "SHIELDS DAMAGED"
11273                 .BYTE $67                             ; "COMPUTER DAMAGED"
11274                 .BYTE $6D                             ; "LONG RANGE SCAN DAMAGED"
11275                 .BYTE $71                             ; "SUB-SPACE RADIO DAMAGED"
11276
11277 ;*** Title phrase offsets of destroyed subsystems ******************************
11278 DESTROYPHRTAB   .BYTE $58                             ; "PHOTON TORPEDOS DESTROYED"
11279                 .BYTE $5E                             ; "ENGINES DESTROYED"
11280                 .BYTE $64                             ; "SHIELDS DESTROYED"
11281                 .BYTE $6A                             ; "COMPUTER DESTROYED"
11282                 .BYTE $6F                             ; "LONG RANGE SCAN DESTROYED"
11283                 .BYTE $73                             ; "SUB-SPACE RADIO DESTROYED"
11284
11285 ;*** 3 x 10-byte noise sound patterns (bytes 0..7 stored in reverse order) *****
11286 ;
11287 ; (9) AUDCTL        ($D208) POKEY: Audio control
11288 ; (8) AUDF3         ($D204) POKEY: Audio channel 3 frequency
11289 ; (7) NOISETORPTIM  ($DA)   Timer for PHOTON TORPEDO LAUNCHED noise sound patterns
11290 ; (6) NOISEEXPLTIM  ($DB)   Timer for SHIELD and ZYLON EXPLOSION noise sound patterns
11291 ; (5) NOISEAUDC2    ($DC)   Audio channel 1/2 control shadow register
11292 ; (4) NOISEAUDC3    ($DD)   Audio channel 3   control shadow register
11293 ; (3) NOISEAUDF1    ($DE)   Audio channel 1 frequency shadow register
11294 ; (2) NOISEAUDF2    ($DF)   Audio channel 2 frequency shadow register
11295 ; (1) NOISEFRQINC   ($E0)   Audio channel 1/2 frequency increment
11296 ; (0) NOISELIFE     ($E1)   Noise sound pattern lifetime
11297 ;
11298 ;                     (0),(1),(2),(3),(4),(5),(6),(7),(8),(9)
11299 NOISEPATTAB     .BYTE $18,$FF,$02,$00,$8A,$A0,$00,$08,$50,$00; PHOTON TORPEDO LAUNCHED
11300                 .BYTE $40,$40,$01,$03,$88,$AF,$08,$00,$50,$04; SHIELD EXPLOSION
11301                 .BYTE $30,$40,$01,$03,$84,$A8,$04,$00,$50,$04; ZYLON EXPLOSION
11302
11303 ;*** 5 x 6-byte beeper sound patterns (bytes 0..5 stored in reverse order) *****
11304 ;
11305 ; (5) BEEPFRQIND    ($D2) Running index into frequency table BEEPFRQTAB ($BF5C)
11306 ; (4) BEEPREPEAT    ($D3) Number of times the beeper sound pattern sequence is repeated - 1
11307 ; (3) BEEPTONELIFE  ($D4) Lifetime of tone in TICKs - 1
11308 ; (2) BEEPPAUSELIFE ($D5) Lifetime of pause in TICKs - 1 ($FF -> No pause)
11309 ; (1) BEEPPRIORITY  ($D6) Beeper sound pattern priority. A playing beeper sound pattern is
11310 ;                         stopped if a beeper sound pattern of higher priority is about to be
11311 ;                         played. A value of 0 indicates that no beeper sound pattern is
11312 ;                         playing at the moment.
11313 ; (0) BEEPFRQSTART  ($D7) Index to first byte of the beeper sound pattern frequency in table
11314 ;                         BEEPFRQTAB ($BF5C)
11315 ;
11316 ; Frequency-over-TICKs diagrams for all beeper sound patterns:
11317 ;
11318 ; HYPERWARP TRANSIT
11319 ;
11320 ;      FRQ
11321 ;       |
11322 ;   $18 |-4--
11323 ;       |
11324 ;   $00 |    -3-
11325 ;       +-------> TICKS
11326 ;        <13 x >
11327 ;
11328 ; RED ALERT
11329 ;
11330 ;      FRQ
11331 ;       |
11332 ;   $60 |                 --------17-------
11333 ;       |
11334 ;   $40 |--------17-------
11335 ;       |
11336 ;       +----------------------------------> TICKS
11337 ;        <-------------- 8 x ------------->
11338 ;
11339 ; ACKNOWLEDGE
11340 ;
11341 ;      FRQ
11342 ;       |
11343 ;   $10 |-3-   -3-   -3-
11344 ;       |
11345 ;   $00 |   -3-   -3-   -3-
11346 ;       +------------------> TICKS
11347 ;        <------ 1 x ----->
11348 ;
11349 ; DAMAGE REPORT (not to scale)
11350 ;
11351 ;      FRQ
11352 ;       |
11353 ;   $40 |------------33-------------
11354 ;       |
11355 ;   $20 |                           ------------33-------------
11356 ;       |
11357 ;       +------------------------------------------------------> TICKS
11358 ;        <------------------------ 3 x ----------------------->
11359 ;
11360 ; MESSAGE FROM STARBASE (not to scale)
11361 ;
11362 ;      FRQ
11363 ;       |
11364 ;   $51 |                                  -----33-----
11365 ;   $48 |-----33-----
11366 ;   $40 |                 -----33-----
11367 ;       |
11368 ;   $00 |            --9--            --9--            --9--
11369 ;       +----------------------------------------------------> TICKS
11370 ;        <---------------------- 1 x ---------------------->
11371 ;
11372 ;                     (0),(1),(2),(3),(4),(5)
11373 BEEPPATTAB      .BYTE $02,$02,$02,$03,$0C,$02         ; HYPERWARP TRANSIT
11374                 .BYTE $04,$03,$FF,$10,$07,$04         ; RED ALERT
11375                 .BYTE $07,$04,$02,$02,$00,$07         ; ACKNOWLEDGE
11376                 .BYTE $0B,$05,$FF,$20,$02,$0B         ; DAMAGE REPORT
11377                 .BYTE $0E,$06,$08,$20,$00,$0E         ; MESSAGE FROM STARBASE
11378
11379 ;*** Beeper sound pattern frequency table **************************************
11380 BEEPFRQTAB      .BYTE $10,$FF                         ; (unused) (!)
11381                 .BYTE $18,$FF                         ; HYPERWARP TRANSIT
11382                 .BYTE $40,$60,$FF                     ; RED ALERT
11383                 .BYTE $10,$10,$10,$FF                 ; ACKNOWLEDGE
11384                 .BYTE $40,$20,$FF                     ; DAMAGE REPORT
11385                 .BYTE $48,$40,$51,$FF                 ; MESSAGE FROM STARBASE
11386
11387 ;*** Shape of blip in Attack Computer Display **********************************
11388 BLIPSHAPTAB     .BYTE $84                             ; #....#..
11389                 .BYTE $B4                             ; #.##.#..
11390                 .BYTE $FC                             ; ######..
11391                 .BYTE $B4                             ; #.##.#..
11392                 .BYTE $84                             ; #....#..
11393
11394 ;*** Initial x-coordinate (high byte) of our starship's photon torpedo *********
11395 BARRELXTAB      .BYTE $FF                             ; Left barrel  = -256 (-$FF00) <KM>
11396                 .BYTE $01                             ; Right barrel = +256 (+$0100) <KM>
11397
11398 ;*** Maximum photon torpedo hit z-coordinate (high byte) ***********************
11399 HITMAXZTAB      .BYTE $0C                             ; < 3328 ($0C**) <KM>
11400                 .BYTE $0C                             ; < 3328 ($0C**) <KM>
11401                 .BYTE $0C                             ; < 3328 ($0C**) <KM>
11402                 .BYTE $0C                             ; < 3328 ($0C**) <KM>
11403                 .BYTE $0E                             ; < 3840 ($0E**) <KM>
11404                 .BYTE $0E                             ; < 3840 ($0E**) <KM>
11405                 .BYTE $0E                             ; < 3840 ($0E**) <KM>
11406                 .BYTE $20                             ; < 8448 ($20**) <KM>
11407
11408 ;*** Minimum photon torpedo hit z-coordinate (high byte) ***********************
11409 HITMINZTAB      .BYTE $00                             ; >=    0 ($00**) <KM>
11410                 .BYTE $00                             ; >=    0 ($00**) <KM>
11411                 .BYTE $00                             ; >=    0 ($00**) <KM>
11412                 .BYTE $02                             ; >=  512 ($02**) <KM>
11413                 .BYTE $04                             ; >= 1024 ($04**) <KM>
11414                 .BYTE $06                             ; >= 1536 ($06**) <KM>
11415                 .BYTE $08                             ; >= 2048 ($08**) <KM>
11416                 .BYTE $0C                             ; >= 3072 ($0C**) <KM>
11417
11418 ;*** Velocity of homing Zylon photon torpedo ***********************************
11419 ZYLONHOMVELTAB  .BYTE NEG!1                           ;  -1 <KM/H> NOVICE mission
11420                 .BYTE NEG!4                           ;  -4 <KM/H> PILOT mission
11421                 .BYTE NEG!8                           ;  -8 <KM/H> WARRIOR mission
11422                 .BYTE NEG!20                          ; -20 <KM/H> COMMANDER mission
11423
11424 ;*** Zylon shape type table ****************************************************
11425 ZYLONSHAPTAB    .BYTE SHAP.ZBASESTAR                  ; ZYLON BASESTAR
11426                 .BYTE SHAP.ZFIGHTER                   ; ZYLON FIGHTER
11427                 .BYTE SHAP.ZFIGHTER                   ; ZYLON FIGHTER
11428                 .BYTE SHAP.ZFIGHTER                   ; ZYLON FIGHTER
11429                 .BYTE SHAP.ZCRUISER                   ; ZYLON CRUISER
11430                 .BYTE SHAP.ZCRUISER                   ; ZYLON CRUISER
11431                 .BYTE SHAP.ZCRUISER                   ; ZYLON CRUISER
11432                 .BYTE SHAP.ZFIGHTER                   ; ZYLON FIGHTER
11433
11434 ;*** Zylon flight pattern table ************************************************
11435 ZYLONFLPATTAB   .BYTE 4                               ; Flight pattern 4
11436                 .BYTE 4                               ; Flight pattern 4
11437                 .BYTE 0                               ; Attack Flight Pattern 0
11438                 .BYTE 0                               ; Attack Flight Pattern 0
11439                 .BYTE 0                               ; Attack Flight Pattern 0
11440                 .BYTE 1                               ; Flight pattern 1
11441                 .BYTE 0                               ; Attack Flight Pattern 0
11442                 .BYTE 0                               ; Attack Flight Pattern 0
11443
11444 ;*** Zylon velocity table ******************************************************
11445 ZYLONVELTAB     .BYTE 62                              ; +62 <KM/H>
11446                 .BYTE 30                              ; +30 <KM/H>
11447                 .BYTE 16                              ; +16 <KM/H>
11448                 .BYTE 8                               ;  +8 <KM/H>
11449                 .BYTE 4                               ;  +4 <KM/H>
11450                 .BYTE 2                               ;  +2 <KM/H>
11451                 .BYTE 1                               ;  +1 <KM/H>
11452                 .BYTE 0                               ;   0 <KM/H>
11453                 .BYTE 0                               ;   0 <KM/H>
11454                 .BYTE NEG!1                           ;  -1 <KM/H>
11455                 .BYTE NEG!2                           ;  -2 <KM/H>
11456                 .BYTE NEG!4                           ;  -4 <KM/H>
11457                 .BYTE NEG!8                           ;  -8 <KM/H>
11458                 .BYTE NEG!16                          ; -16 <KM/H>
11459                 .BYTE NEG!30                          ; -30 <KM/H>
11460                 .BYTE NEG!62                          ; -62 <KM/H>
11461
11462 ;*** PLAYFIELD colors (including PLAYFIELD colors during DLI) ******************
11463 PFCOLORTAB      .BYTE $A6                             ; PF0COLOR    = {GREEN}
11464                 .BYTE $AA                             ; PF1COLOR    = {LIGHT GREEN}
11465                 .BYTE $AF                             ; PF2COLOR    = {VERY LIGHT GREEN}
11466                 .BYTE $00                             ; PF3COLOR    = {BLACK}
11467                 .BYTE $00                             ; BGRCOLOR    = {BLACK}
11468                 .BYTE $B8                             ; PF0COLORDLI = {LIGHT MINT}
11469                 .BYTE $5A                             ; PF1COLORDLI = {MEDIUM PINK}
11470                 .BYTE $FC                             ; PF2COLORDLI = {LIGHT ORANGE}
11471                 .BYTE $5E                             ; PF3COLORDLI = {LIGHT PINK}
11472                 .BYTE $90                             ; BGRCOLORDLI = {DARK BLUE}
11473
11474 ;*** Vicinity mask table. Confines coordinates of space objects in sector ******
11475 VICINITYMASKTAB .BYTE $FF                             ; <= 65535 ($FF**) <KM>
11476                 .BYTE $FF                             ; <= 65535 ($FF**) <KM>
11477                 .BYTE $3F                             ; <= 16383 ($3F**) <KM>
11478                 .BYTE $0F                             ; <=  4095 ($0F**) <KM>
11479                 .BYTE $3F                             ; <= 16383 ($3F**) <KM>
11480                 .BYTE $7F                             ; <= 32767 ($7F**) <KM>
11481                 .BYTE $FF                             ; <= 65535 ($FF**) <KM>
11482                 .BYTE $FF                             ; <= 65535 ($FF**) <KM>
11483
11484 ;*** Movement probability of sector types in Galactic Chart ********************
11485 MOVEPROBTAB     .BYTE 0                               ; Empty sector    0% (  0:256)
11486                 .BYTE 255                             ; 1 Zylon ship  100% (255:256)
11487                 .BYTE 255                             ; 2 Zylon ships 100% (255:256)
11488                 .BYTE 192                             ; 3 Zylon ships  75% (192:256)
11489                 .BYTE 32                              ; 4 Zylon ships  13% ( 32:256)
11490
11491 ;*** Galactic Chart sector offset to adjacent sector ***************************
11492 COMPASSOFFTAB   .BYTE -16                             ; NORTH
11493                 .BYTE -17                             ; NORTHWEST
11494                 .BYTE -1                              ; WEST
11495                 .BYTE 15                              ; SOUTHWEST
11496                 .BYTE 16                              ; SOUTH
11497                 .BYTE 17                              ; SOUTHEAST
11498                 .BYTE 1                               ; EAST
11499                 .BYTE -15                             ; NORTHEAST
11500                 .BYTE 0                               ; CENTER
11501
11502 ;*** Homing velocities of photon torpedoes 0..1 depending on distance to target 
11503 HOMVELTAB       .BYTE 0                               ;  +0 <KM/H>
11504                 .BYTE 8                               ;  +8 <KM/H>
11505                 .BYTE 16                              ; +16 <KM/H>
11506                 .BYTE 24                              ; +24 <KM/H>
11507                 .BYTE 40                              ; +40 <KM/H>
11508                 .BYTE 48                              ; +48 <KM/H>
11509                 .BYTE 56                              ; +56 <KM/H>
11510                 .BYTE 64                              ; +64 <KM/H>
11511
11512 ;*** PLAYER shape color table (bits B7..4 of color/brightness) *****************
11513 PLSHAPCOLORTAB  .BYTE $50                             ; PHOTON TORPEDO          = {PURPLE}
11514                 .BYTE $00                             ; ZYLON FIGHTER           = {GRAY}
11515                 .BYTE $20                             ; STARBASE RIGHT          = {ORANGE}
11516                 .BYTE $20                             ; STARBASE CENTER         = {ORANGE}
11517                 .BYTE $20                             ; STARBASE LEFT           = {ORANGE}
11518                 .BYTE $00                             ; TRANSFER VESSEL         = {GRAY}
11519                 .BYTE $A0                             ; METEOR                  = {GREEN}
11520                 .BYTE $00                             ; ZYLON CRUISER           = {GRAY}
11521                 .BYTE $00                             ; ZYLON BASESTAR          = {GRAY}
11522                 .BYTE $9F                             ; HYPERWARP TARGET MARKER = {SKY BLUE}
11523
11524 ;*** PLAYER shape brightness table (bits B3..0 of color/brightness) ************
11525 PLSHAPBRITTAB   .BYTE $0E                             ; ##############..
11526                 .BYTE $0E                             ; ##############..
11527                 .BYTE $0E                             ; ##############..
11528                 .BYTE $0C                             ; ############....
11529                 .BYTE $0C                             ; ############....
11530                 .BYTE $0C                             ; ############....
11531                 .BYTE $0A                             ; ##########......
11532                 .BYTE $0A                             ; ##########......
11533                 .BYTE $0A                             ; ##########......
11534                 .BYTE $08                             ; ########........
11535                 .BYTE $08                             ; ########........
11536                 .BYTE $08                             ; ########........
11537                 .BYTE $06                             ; ######..........
11538                 .BYTE $06                             ; ######..........
11539                 .BYTE $04                             ; ####............
11540                 .BYTE $04                             ; ####............
11541
11542 ;*** PHOTON TORPEDO LAUNCHED noise bit and volume (stored in reverse order) ****
11543 NOISETORPVOLTAB .BYTE $8A                             ; ##########.....
11544                 .BYTE $8F                             ; ###############
11545                 .BYTE $8D                             ; #############..
11546                 .BYTE $8B                             ; ###########....
11547                 .BYTE $89                             ; #########......
11548                 .BYTE $87                             ; #######........
11549                 .BYTE $85                             ; ######.........
11550                 .BYTE $83                             ; ###............
11551
11552 ;*** PHOTON TORPEDO LAUNCHED noise frequency table (stored in reverse order) ***
11553 NOISETORPFRQTAB .BYTE $00                             ;
11554                 .BYTE $04                             ;
11555                 .BYTE $01                             ;
11556                 .BYTE $04                             ;
11557                 .BYTE $01                             ;
11558                 .BYTE $04                             ;
11559                 .BYTE $01                             ;
11560                 .BYTE $04                             ;
11561
11562                 .BYTE $07                             ; (unused)
11563
11564                 .BYTE $00                             ; Always 0 for cartridges
11565                 .BYTE $80                             ; On SYSTEM RESET jump to INITCOLD via
11566                 .WORD INITCOLD                        ; Cartridge Initialization Address
